state-in-url 4.3.3 → 5.1.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 +89 -1
- package/dist/constants/constants.js +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/encodeState/encodeState.js +1 -0
- package/dist/encodeState/index.js +1 -0
- package/dist/encoder/encoder.js +1 -0
- package/dist/encoder/index.js +1 -0
- package/dist/index.js +1 -0
- package/dist/next/index.js +1 -0
- package/dist/next/useUrlState/index.js +1 -0
- package/dist/next/useUrlState/useUrlState.d.ts +0 -30
- package/dist/next/useUrlState/useUrlState.js +1 -0
- package/dist/next/useUrlState/useUrlState.mjs +1 -1
- package/dist/parseSPObj.js +1 -0
- package/dist/react-router/index.js +1 -0
- package/dist/react-router/useUrlState/index.js +1 -0
- package/dist/react-router/useUrlState/useUrlState.d.ts +0 -26
- package/dist/react-router/useUrlState/useUrlState.js +1 -0
- package/dist/react-router/useUrlState/useUrlState.mjs +1 -1
- package/dist/remix/index.d.ts +1 -0
- package/dist/remix/index.js +1 -0
- package/dist/remix/index.mjs +1 -0
- package/dist/remix/useUrlState/index.d.ts +1 -0
- package/dist/remix/useUrlState/index.js +1 -0
- package/dist/remix/useUrlState/index.mjs +1 -0
- package/dist/remix/useUrlState/useUrlState.d.ts +82 -0
- package/dist/remix/useUrlState/useUrlState.js +1 -0
- package/dist/remix/useUrlState/useUrlState.mjs +1 -0
- package/dist/subscribers.js +1 -0
- package/dist/useInsertionEffect.js +1 -0
- package/dist/useSharedState/index.js +1 -0
- package/dist/useSharedState/useSharedState.js +1 -0
- package/dist/useUrlEncode/index.js +1 -0
- package/dist/useUrlEncode/useUrlEncode.js +1 -0
- package/dist/useUrlEncode/useUrlEncode.mjs +1 -1
- package/dist/useUrlStateBase/index.js +1 -0
- package/dist/useUrlStateBase/useUrlStateBase.js +1 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -0
- package/package.json +63 -17
package/README.md
CHANGED
|
@@ -102,6 +102,7 @@ This library is a good alternative for NUQS.
|
|
|
102
102
|
- [Installation](#installation)
|
|
103
103
|
- [useUrlState hook](#useurlstate)
|
|
104
104
|
- - [Next.js](#useurlstate-hook-for-nextjs)
|
|
105
|
+
- - [Remix](#useurlstate-hook-for-remixjs)
|
|
105
106
|
- - [React-Router](#useurlstate-hook-for-react-router)
|
|
106
107
|
- [Other helpers](#other-hooks-and-helpers)
|
|
107
108
|
- - [`useUrlStateBase` for other routers](#useurlstatebase-hook-for-others-routers)
|
|
@@ -454,6 +455,93 @@ function SettingsComponent() {
|
|
|
454
455
|
|
|
455
456
|
</details>
|
|
456
457
|
|
|
458
|
+
### useUrlState hook for Remix.js
|
|
459
|
+
|
|
460
|
+
API is same as for Next.js version, except can pass options from [NavigateOptions](https://github.com/remix-run/react-router/blob/bc693ed9f39170bda13b9e1b282fb8e9d5925f66/packages/react-router/lib/context.ts#L99) type.
|
|
461
|
+
|
|
462
|
+
[API Docs](packages/urlstate/remix/useUrlState)
|
|
463
|
+
|
|
464
|
+
#### Example
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
export const form: Form = {
|
|
468
|
+
name: '',
|
|
469
|
+
age: undefined,
|
|
470
|
+
agree_to_terms: false,
|
|
471
|
+
tags: [],
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
type Form = {
|
|
475
|
+
name: string;
|
|
476
|
+
age?: number;
|
|
477
|
+
agree_to_terms: boolean;
|
|
478
|
+
tags: { id: string; value: { text: string; time: Date } }[];
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
```typescript
|
|
484
|
+
import { useUrlState } from 'state-in-url/remix';
|
|
485
|
+
|
|
486
|
+
import { form } from './form';
|
|
487
|
+
|
|
488
|
+
function TagsComponent() {
|
|
489
|
+
const { urlState, setUrl, setState } = useUrlState(form);
|
|
490
|
+
|
|
491
|
+
const onChangeTags = React.useCallback(
|
|
492
|
+
(tag: (typeof tags)[number]) => {
|
|
493
|
+
setUrl((curr) => ({
|
|
494
|
+
...curr,
|
|
495
|
+
tags: curr.tags.find((t) => t.id === tag.id)
|
|
496
|
+
? curr.tags.filter((t) => t.id !== tag.id)
|
|
497
|
+
: curr.tags.concat(tag),
|
|
498
|
+
}));
|
|
499
|
+
},
|
|
500
|
+
[setUrl],
|
|
501
|
+
);
|
|
502
|
+
|
|
503
|
+
return (
|
|
504
|
+
<div>
|
|
505
|
+
<Field text="Tags">
|
|
506
|
+
<div className="flex flex-wrap gap-2">
|
|
507
|
+
{tags.map((tag) => (
|
|
508
|
+
<Tag
|
|
509
|
+
active={!!urlState.tags.find((t) => t.id === tag.id)}
|
|
510
|
+
text={tag.value.text}
|
|
511
|
+
onClick={() => onChangeTags(tag)}
|
|
512
|
+
key={tag.id}
|
|
513
|
+
/>
|
|
514
|
+
))}
|
|
515
|
+
</div>
|
|
516
|
+
</Field>
|
|
517
|
+
|
|
518
|
+
<input value={urlState.name}
|
|
519
|
+
onChange={(ev) => { setState(curr => ({ ...curr, name: ev.target.value })) }}
|
|
520
|
+
// Can update state immediately but sync change to url as needed
|
|
521
|
+
onBlur={() => setUrl()}
|
|
522
|
+
/>
|
|
523
|
+
</div>
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
const tags = [
|
|
528
|
+
{
|
|
529
|
+
id: '1',
|
|
530
|
+
value: { text: 'React.js', time: new Date('2024-07-17T04:53:17.000Z') },
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
id: '2',
|
|
534
|
+
value: { text: 'Next.js', time: new Date('2024-07-18T04:53:17.000Z') },
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
id: '3',
|
|
538
|
+
value: { text: 'TailwindCSS', time: new Date('2024-07-19T04:53:17.000Z') },
|
|
539
|
+
},
|
|
540
|
+
];
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
[Example code](packages/example-remix2/app/routes/Form-for-test.tsx)
|
|
544
|
+
|
|
457
545
|
### useUrlState hook for React-Router
|
|
458
546
|
|
|
459
547
|
API is same as for Next.js version, except can pass options from [NavigateOptions](https://github.com/remix-run/react-router/blob/bc693ed9f39170bda13b9e1b282fb8e9d5925f66/packages/react-router/lib/context.ts#L99) type.
|
|
@@ -629,7 +717,7 @@ See [Contributing doc](CONTRIBUTING.md)
|
|
|
629
717
|
|
|
630
718
|
- [x] hook for `Next.js`
|
|
631
719
|
- [x] hook for `react-router`
|
|
632
|
-
- [
|
|
720
|
+
- [x] hook for `remix`
|
|
633
721
|
- [ ] hook for `svelte`
|
|
634
722
|
- [ ] hook for `astro`
|
|
635
723
|
- [ ] hook for store state in hash ?
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("../utils.js");const i={date:"\u23F2",undefined:"\u2219undefined"};const u=e.isSafari?330:70;exports.SYMBOLS=i;exports.TIMEOUT=u;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var r=require("./constants.js");exports.SYMBOLS=r.SYMBOLS;exports.TIMEOUT=r.TIMEOUT;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var i=require("../encoder/encoder.js");var s=require("../utils.js");function d(o,t,r){const n=s.getParams(r);for(const[e,c]of Object.entries(o||{})){const a=t?.[e];if(JSON.stringify(c)!==JSON.stringify(a)){n.set(e,i.encode(c))}}return n.toString()}function u(o,t){return{...t||{},...Object.fromEntries([...s.getParams(o).entries()].map(([r,n])=>{const e=t?.[r];return[r,i.decode(n,e)??e]}))}}exports.decodeState=u;exports.encodeState=d;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./encodeState.js");exports.decodeState=e.decodeState;exports.encodeState=e.encodeState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var n=require("../constants/constants.js");var o=require("../utils.js");function S(e){if(typeof e==="function"||typeof e==="symbol")return"";if(v(e)){return e}return JSON.stringify(structuredClone(e),c).replace(/'/g,"%27").replace(/"/g,"'")}function c(e,r){const i=o.typeOf(r);if(i!=="object"&&i!=="array"){return s(r)}if(i==="object"){const t=r;for(const u of Object.keys(t)){t[u]=c(e,t[u])}return t}if(i==="array"){return r.map(t=>c(e,t))}return r}const s=e=>{switch(o.typeOf(e)){case"date":return n.SYMBOLS.date+new Date(e).toISOString();case"undefined":return n.SYMBOLS.undefined;default:return e}};function p(e,r){return d(e.replace(/'/g,'"').replace(/%27/g,"'"),r)}function d(e,r){try{return JSON.parse(e,a)}catch{return r}}function a(e,r){return typeof r==="string"?f(r):r}const f=e=>{if(e===n.SYMBOLS.undefined)return void 0;if(e?.startsWith?.(n.SYMBOLS.date))return new Date(e.slice(1));return e};const O=new RegExp(`^(${n.SYMBOLS.undefined}|${n.SYMBOLS.date})`);const v=e=>O.test(String(e));exports.decode=p;exports.decodePrimitive=f;exports.encode=S;exports.encodePrimitive=s;exports.parseJSON=d;exports.reviver=a;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./encoder.js");exports.decode=e.decode;exports.encode=e.encode;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./encoder/encoder.js");var r=require("./encodeState/encodeState.js");var a=require("./next/useUrlState/useUrlState.js");var u=require("./useSharedState/useSharedState.js");var S=require("./useUrlEncode/useUrlEncode.js");var d=require("./useUrlStateBase/useUrlStateBase.js");var t=require("./utils.js");exports.decode=e.decode;exports.encode=e.encode;exports.decodeState=r.decodeState;exports.encodeState=r.encodeState;exports.useUrlState=a.useUrlState;exports.useSharedState=u.useSharedState;exports.useUrlEncode=S.useUrlEncode;exports.useUrlStateBase=d.useUrlStateBase;exports.isSSR=t.isSSR;exports.typeOf=t.typeOf;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlState/useUrlState.js");exports.useUrlState=e.useUrlState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlState.js");exports.useUrlState=e.useUrlState;
|
|
@@ -1,28 +1,5 @@
|
|
|
1
1
|
import { useRouter } from "next/navigation";
|
|
2
2
|
import { type JSONCompatible } from "../../utils";
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated .
|
|
5
|
-
* * use format `useUrlState(defaultState, { ...otherParams })`
|
|
6
|
-
*
|
|
7
|
-
* .
|
|
8
|
-
*/
|
|
9
|
-
export declare function useUrlState<T extends JSONCompatible>({ defaultState: T, searchParams, replace, scroll, useHistory, }: OldParams<T>): {
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated use `urlState`
|
|
12
|
-
*/
|
|
13
|
-
state: T;
|
|
14
|
-
urlState: T;
|
|
15
|
-
/**
|
|
16
|
-
* @deprecated use `setState`
|
|
17
|
-
*/
|
|
18
|
-
updateState: (value: Partial<T> | ((currState: T) => T)) => void;
|
|
19
|
-
setState: (value: Partial<T> | ((currState: T) => T)) => void;
|
|
20
|
-
/**
|
|
21
|
-
* @deprecated use `setUrl`
|
|
22
|
-
*/
|
|
23
|
-
updateUrl: (value?: Partial<T> | ((currState: T) => T)) => void;
|
|
24
|
-
setUrl: (value?: Partial<T> | ((currState: T) => T)) => void;
|
|
25
|
-
};
|
|
26
3
|
/**
|
|
27
4
|
* NextJS hook. Returns `urlState`, `setState`, and `setUrl` functions
|
|
28
5
|
*
|
|
@@ -103,13 +80,6 @@ type RouterOptions = NonNullable<Parameters<Router["push"]>[1] | Parameters<Rout
|
|
|
103
80
|
interface Options extends RouterOptions {
|
|
104
81
|
replace?: boolean;
|
|
105
82
|
}
|
|
106
|
-
interface OldParams<T> {
|
|
107
|
-
defaultState: T;
|
|
108
|
-
searchParams?: object;
|
|
109
|
-
replace?: boolean;
|
|
110
|
-
scroll?: boolean;
|
|
111
|
-
useHistory?: boolean;
|
|
112
|
-
}
|
|
113
83
|
type Params = {
|
|
114
84
|
searchParams?: object;
|
|
115
85
|
replace?: boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var h=require("react");var p=require("next/navigation");var S=require("../../parseSPObj.js");var k=require("../../useUrlStateBase/useUrlStateBase.js");var r=require("../../utils.js");function q(e){return e&&e.__esModule?e:{default:e}}var s=q(h);function _(e,a){const u=a?.useHistory;const l=p.useRouter();const d=s.default.useMemo(()=>({push:(...t)=>{if(u===void 0?true:!!u){r.routerHistory.push(...t)}else{l.push(...t)}},replace:(...t)=>{if(u===void 0?true:!!u){r.routerHistory.replace(...t)}else{l.replace(...t)}}}),[l]);const{state:P,updateState:o,updateUrl:n,reset:c,getState:U}=k.useUrlStateBase(e,d,({parse:t})=>{return r.isSSR?S.parseSPObj(r.filterUnknownParams(e,a?.searchParams),e):t(r.filterUnknownParamsClient(e,a?.searchParams))});const i=s.default.useMemo(()=>({...j,scroll:a?.scroll,replace:a?.replace}),[]);const m=s.default.useCallback((t,b)=>n(t,{...i,...b}),[n]);const f=p.useSearchParams();s.default.useLayoutEffect(()=>{o(r.filterUnknownParams(e,S.parseSPObj(Object.fromEntries([...f.entries()]),e)))},[f]);const v=s.default.useCallback(t=>{c({...i,...t})},[c]);return{setState:o,setUrl:m,urlState:P,reset:v,getState:U}}const j={replace:true,scroll:false};exports.useUrlState=_;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import s from"react";import{useRouter as k,useSearchParams as C}from"next/navigation";import{parseSPObj as p}from"../../parseSPObj.mjs";import{useUrlStateBase as y}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as m,filterUnknownParams as f,isSSR as g,filterUnknownParamsClient as j}from"../../utils.mjs";function v(t,r){const a=r?.useHistory;const o=k();const S=s.useMemo(()=>({push:(...e)=>{if(a===void 0?true:!!a){m.push(...e)}else{o.push(...e)}},replace:(...e)=>{if(a===void 0?true:!!a){m.replace(...e)}else{o.replace(...e)}}}),[o]);const{state:h,updateState:l,updateUrl:c,reset:u,getState:P}=y(t,S,({parse:e})=>{return g?p(f(t,r?.searchParams),t):e(j(t,r?.searchParams))});const n=s.useMemo(()=>({...w,scroll:r?.scroll,replace:r?.replace}),[]);const U=s.useCallback((e,d)=>c(e,{...n,...d}),[c]);const i=C();s.useLayoutEffect(()=>{l(f(t,p(Object.fromEntries([...i.entries()]),t)))},[i]);const b=s.useCallback(e=>{u({...n,...e})},[u]);return{setState:l,setUrl:U,urlState:h,reset:b,getState:P}}const w={replace:true,scroll:false};export{v as useUrlState};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var c=require("./encoder/encoder.js");function s(r,e){return{...e,...o(JSON.stringify(r),e)}}function o(r,e){try{return JSON.parse(r,u)}catch{return e}}const u=(r,e)=>{const t=typeof e==="string";const n=t&&c.decode(e?.replace?.(/'/g,'"'));return r&&t?n:e};exports.parseSPObj=s;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlState/useUrlState.js");exports.useUrlState=e.useUrlState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlState.js");exports.useUrlState=e.useUrlState;
|
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
import { type NavigateOptions } from "react-router-dom";
|
|
2
2
|
import { type JSONCompatible } from "../../utils";
|
|
3
|
-
/**
|
|
4
|
-
* @deprecated .
|
|
5
|
-
* * use format `useUrlState(defaultState, { ...otherParams })`
|
|
6
|
-
*
|
|
7
|
-
* .
|
|
8
|
-
*/
|
|
9
|
-
export declare function useUrlState<T extends JSONCompatible>({ defaultState: T, searchParams, replace, useHistory, }: OldParams<T>): {
|
|
10
|
-
/**
|
|
11
|
-
* @deprecated use `urlState`
|
|
12
|
-
*/
|
|
13
|
-
state: T;
|
|
14
|
-
urlState: T;
|
|
15
|
-
/**
|
|
16
|
-
* @deprecated use `setState`
|
|
17
|
-
*/
|
|
18
|
-
updateState: (value: Partial<T> | ((currState: T) => T)) => void;
|
|
19
|
-
setState: (value: Partial<T> | ((currState: T) => T)) => void;
|
|
20
|
-
updateUrl: (value?: Partial<T> | ((currState: T) => T)) => void;
|
|
21
|
-
setUrl: (value?: Partial<T> | ((currState: T) => T)) => void;
|
|
22
|
-
};
|
|
23
3
|
/**
|
|
24
4
|
* React-router hook. Returns `urlState`, `setState`, and `setUrl` functions
|
|
25
5
|
*
|
|
@@ -94,12 +74,6 @@ export declare function useUrlState<T extends JSONCompatible>(defaultState: T, p
|
|
|
94
74
|
[key: string]: unknown;
|
|
95
75
|
}) => void;
|
|
96
76
|
};
|
|
97
|
-
type OldParams<T> = {
|
|
98
|
-
defaultState: T;
|
|
99
|
-
useHistory?: boolean;
|
|
100
|
-
searchParams?: object;
|
|
101
|
-
replace?: boolean;
|
|
102
|
-
} & NavigateOptions;
|
|
103
77
|
interface Params extends NavigateOptions {
|
|
104
78
|
useHistory?: boolean;
|
|
105
79
|
searchParams?: object;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var P=require("react");var c=require("react-router-dom");var _=require("../../parseSPObj.js");var g=require("../../useUrlStateBase/useUrlStateBase.js");var u=require("../../utils.js");function k(e){return e&&e.__esModule?e:{default:e}}var s=k(P);function R(e,l){const p=l?.useHistory;const a=s.default.useMemo(()=>({...h,replace:l?.replace,preventScrollReset:l?.preventScrollReset}),[]);const n=c.useNavigate();const v=s.default.useMemo(()=>p?u.routerHistory:{replace:(t,r)=>n(t,{...a,...r}),push:(t,r)=>n(t,{...a,...r})},[n]);const[o]=c.useSearchParams();const d=c.useHref("/");const{state:U,updateState:i,updateUrl:f,getState:m,reset:S}=g.useUrlStateBase(e,v,({parse:t})=>t(u.filterUnknownParamsClient(e,o.entries())),d);const b=s.default.useCallback((t,r)=>f(t,{...a,...r}),[f]);s.default.useEffect(()=>{i(u.assignValue(e,u.filterUnknownParams(e,_.parseSPObj(Object.fromEntries([...o.entries()]),e))))},[o]);const q=s.default.useCallback(t=>{S({...a,...t})},[S]);return{setState:i,setUrl:b,urlState:U,reset:q,getState:m}}const h={replace:true,preventScrollReset:true};exports.useUrlState=R;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import s from"react";import{useNavigate as g,useSearchParams as k,useHref as P}from"react-router-dom";import{parseSPObj as h}from"../../parseSPObj.mjs";import{useUrlStateBase as C}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as H,filterUnknownParamsClient as R,assignValue as d,filterUnknownParams as j}from"../../utils.mjs";function w(t,a){const i=a?.useHistory;const o=s.useMemo(()=>({...y,replace:a?.replace,preventScrollReset:a?.preventScrollReset}),[]);const n=g();const m=s.useMemo(()=>i?H:{replace:(e,r)=>n(e,{...o,...r}),push:(e,r)=>n(e,{...o,...r})},[n]);const[c]=k();const f=P("/");const{state:S,updateState:l,updateUrl:u,getState:U,reset:p}=C(t,m,({parse:e})=>e(R(t,c.entries())),f);const b=s.useCallback((e,r)=>u(e,{...o,...r}),[u]);s.useEffect(()=>{l(d(t,j(t,h(Object.fromEntries([...c.entries()]),t))))},[c]);const v=s.useCallback(e=>{p({...o,...e})},[p]);return{setState:l,setUrl:b,urlState:S,reset:v,getState:U}}const y={replace:true,preventScrollReset:true};export{w as useUrlState};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useUrlState } from "./useUrlState";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlState/useUrlState.js");exports.useUrlState=e.useUrlState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useUrlState as t}from"./useUrlState/useUrlState.mjs";export{t as useUrlState};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useUrlState } from "./useUrlState";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlState.js");exports.useUrlState=e.useUrlState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{useUrlState as t}from"./useUrlState.mjs";export{t as useUrlState};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type NavigateOptions } from "react-router-dom";
|
|
2
|
+
import { type JSONCompatible } from "../../utils";
|
|
3
|
+
/**
|
|
4
|
+
* Remix hook. Returns `urlState`, `setState`, and `setUrl` functions
|
|
5
|
+
*
|
|
6
|
+
* @param {JSONCompatible<T>} [defaultState] Fallback (default) values for state
|
|
7
|
+
* @param {Object} params - Object with other parameters
|
|
8
|
+
* @param {NavigateOptions} params.NavigateOptions See type from [`react-router-dom`](https://api.reactrouter.com/v7/interfaces/react_router.NavigateOptions.html)
|
|
9
|
+
* @param {boolean} params.replace replace URL or push, default `true`
|
|
10
|
+
* @param {boolean} params.useHistory use window.history for navigation, default `false`
|
|
11
|
+
* @param {boolean} params.preventScrollReset keep scroll position, default `true`
|
|
12
|
+
* @returns {Object} [result] State and callbacks
|
|
13
|
+
* @returns {Object} [result.state] - current state object
|
|
14
|
+
* @returns {Function} [result.setUrl] - function to update state and url
|
|
15
|
+
* @returns {Function} [result.setState] - function to update state only
|
|
16
|
+
* @returns {Function} [result.reset] - function to reset state and url to default
|
|
17
|
+
* * Example:
|
|
18
|
+
* ```ts
|
|
19
|
+
* export const form = { name: '', age: 0 };
|
|
20
|
+
* const { urlState, setState, setUrl } = useUrlState(form, { replace: false, preventScrollReset: false });
|
|
21
|
+
*
|
|
22
|
+
* setState({ name: 'test' });
|
|
23
|
+
* setUrl({ name: 'test' }, { replace: true });
|
|
24
|
+
* // similar to React.useState
|
|
25
|
+
* setUrl(curr => ({ ...curr, name: 'test' }), { replace: true });
|
|
26
|
+
* // reset state and url
|
|
27
|
+
* reset();
|
|
28
|
+
* reset({ replace: true });
|
|
29
|
+
* // same as setState(form) with setUrl(form)
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/remix/useUrlState}
|
|
33
|
+
*/
|
|
34
|
+
export declare function useUrlState<T extends JSONCompatible>(defaultState: T, params?: Params): {
|
|
35
|
+
/**
|
|
36
|
+
* State object. Don't mutate directly, use `setState` or `setUrl`
|
|
37
|
+
*/
|
|
38
|
+
urlState: T;
|
|
39
|
+
/**
|
|
40
|
+
* * Example:
|
|
41
|
+
* ```ts
|
|
42
|
+
* setState({ name: 'test' });
|
|
43
|
+
* // or
|
|
44
|
+
* setState(curr => ({ ...curr, name: 'test' }) );
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/remix/useUrlState#updatestate}
|
|
48
|
+
*/
|
|
49
|
+
setState: (value: Partial<T> | ((currState: T) => T)) => void;
|
|
50
|
+
/**
|
|
51
|
+
* * Example:
|
|
52
|
+
* ```ts
|
|
53
|
+
* setUrl({ name: 'test' });
|
|
54
|
+
* // or
|
|
55
|
+
* setUrl(curr => ({ ...curr, name: 'test' }), { replace: true } );
|
|
56
|
+
* // can pass optional React-Router `NavigateOptions`
|
|
57
|
+
* setUrl(curr => ({ ...curr, name: 'test' }), { preventScrollReset: false } );
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/remix/useUrlState#updateurl}
|
|
61
|
+
*/
|
|
62
|
+
setUrl: (value?: Partial<T> | ((currState: T) => T), options?: Params) => void;
|
|
63
|
+
/**
|
|
64
|
+
* * Example:
|
|
65
|
+
* ```ts
|
|
66
|
+
* reset();
|
|
67
|
+
* // or
|
|
68
|
+
* reset({ replace: false, preventScrollReset: false })
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* * Docs {@link https://github.com/asmyshlyaev177/state-in-url/tree/master/packages/urlstate/remix/useUrlState#reset}
|
|
72
|
+
*/
|
|
73
|
+
reset: (options?: NavigateOptions & {
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
}) => void;
|
|
76
|
+
};
|
|
77
|
+
interface Params extends NavigateOptions {
|
|
78
|
+
useHistory?: boolean;
|
|
79
|
+
searchParams?: object;
|
|
80
|
+
replace?: boolean;
|
|
81
|
+
}
|
|
82
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var P=require("react");var o=require("@remix-run/react");var _=require("../../parseSPObj.js");var g=require("../../useUrlStateBase/useUrlStateBase.js");var u=require("../../utils.js");function k(e){return e&&e.__esModule?e:{default:e}}var s=k(P);function h(e,l){const p=l?.useHistory;const a=s.default.useMemo(()=>({...j,replace:l?.replace,preventScrollReset:l?.preventScrollReset}),[]);const n=o.useNavigate();const v=s.default.useMemo(()=>p?u.routerHistory:{replace:(t,r)=>n(t,{...a,...r}),push:(t,r)=>n(t,{...a,...r})},[n]);const[c]=o.useSearchParams();const d=o.useHref("/");const{state:U,updateState:i,updateUrl:f,getState:m,reset:S}=g.useUrlStateBase(e,v,({parse:t})=>t(u.filterUnknownParamsClient(e,c.entries())),d);const b=s.default.useCallback((t,r)=>f(t,{...a,...r}),[f]);s.default.useEffect(()=>{i(u.assignValue(e,u.filterUnknownParams(e,_.parseSPObj(Object.fromEntries([...c.entries()]),e))))},[c]);const q=s.default.useCallback(t=>{S({...a,...t})},[S]);return{setState:i,setUrl:b,urlState:U,reset:q,getState:m}}const j={replace:true,preventScrollReset:true};exports.useUrlState=h;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import s from"react";import{useNavigate as g,useSearchParams as k,useHref as P}from"@remix-run/react";import{parseSPObj as h}from"../../parseSPObj.mjs";import{useUrlStateBase as C}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as H,filterUnknownParamsClient as R,assignValue as d,filterUnknownParams as j}from"../../utils.mjs";function w(t,a){const i=a?.useHistory;const o=s.useMemo(()=>({...y,replace:a?.replace,preventScrollReset:a?.preventScrollReset}),[]);const n=g();const m=s.useMemo(()=>i?H:{replace:(e,r)=>n(e,{...o,...r}),push:(e,r)=>n(e,{...o,...r})},[n]);const[c]=k();const f=P("/");const{state:S,updateState:l,updateUrl:u,getState:U,reset:p}=C(t,m,({parse:e})=>e(R(t,c.entries())),f);const b=s.useCallback((e,r)=>u(e,{...o,...r}),[u]);s.useEffect(()=>{l(d(t,j(t,h(Object.fromEntries([...c.entries()]),t))))},[c]);const v=s.useCallback(e=>{p({...o,...e})},[p]);return{setState:l,setUrl:b,urlState:S,reset:v,getState:U}}const y={replace:true,preventScrollReset:true};export{w as useUrlState};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const r=new WeakMap;const s=new WeakMap;const a={get(t){return s.get(t)||[]},add(t,e){const n=this.get(t);s.set(t,n.concat(e));return()=>this.remove(t,e)},remove(t,e){const n=this.get(t);const c=n.filter(o=>o!==e);if(c.length){s.set(t,c)}else{s.delete(t)}}};const i={get:function(t){return r.get(t)},set:function(t,e){r.set(t,e)}};exports.stateMap=i;exports.subscribers=a;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var f=require("react");function u(e){return e&&e.__esModule?e:{default:e}}var t=u(f);const s=t.default.useInsertionEffect||t.default.useEffect;exports.useInsertionEffect=s;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useSharedState.js");exports.useSharedState=e.useSharedState;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var b=require("react");var u=require("../subscribers.js");var M=require("../useInsertionEffect.js");var i=require("../utils.js");function g(s){return s&&s.__esModule?s:{default:s}}var n=g(b);function v(s,a){const t=n.default.useRef(s);const[f,o]=n.default.useState(()=>{if(i.isSSR){return a?a?.():t.current}const e=u.stateMap.get(t.current);if(!e){const r=a?.()||t.current;u.stateMap.set(t.current,r);return r}else{return e}});const l=n.default.useCallback(e=>{const r=u.stateMap.get(t.current);const S=typeof e==="function";const c=S?e(r):{...r,...e};if(i.isEqual(r,c))return void 0;u.stateMap.set(t.current,c);u.subscribers.get(t.current).forEach(p=>p())},[]);M.useInsertionEffect(()=>{const e=()=>{o(u.stateMap.get(t.current)||t.current)};const r=u.subscribers.add(t.current,e);return()=>{r()}},[]);const d=n.default.useCallback(()=>u.stateMap.get(t.current)||t.current,[]);return{state:f,getState:d,setState:l}}exports.useSharedState=v;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlEncode.js");exports.useUrlEncode=e.useUrlEncode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var c=require("react");var r=require("../encodeState/encodeState.js");var l=require("../utils.js");function d(e){return e&&e.__esModule?e:{default:e}}var u=d(c);function i(e){const a=u.default.useCallback((t,s)=>{return l.typeOf(t)==="object"?r.encodeState(t,e,s):""},[e]);const n=u.default.useCallback(t=>r.decodeState(t,e),[e]);return{parse:n,stringify:a}}exports.useUrlEncode=i;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import r from"react";import{encodeState as
|
|
1
|
+
import r from"react";import{encodeState as s,decodeState as a}from"../encodeState/encodeState.mjs";import{typeOf as f}from"../utils.mjs";function i(e){const o=r.useCallback((t,c)=>{return f(t)==="object"?s(t,e,c):""},[e]);const n=r.useCallback(t=>a(t,e),[e]);return{parse:n,stringify:o}}export{i as useUrlEncode};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var e=require("./useUrlStateBase.js");exports.useUrlStateBase=e.useUrlStateBase;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var y=require("react");var R=require("../constants/constants.js");var T=require("../useInsertionEffect.js");var _=require("../useSharedState/useSharedState.js");var b=require("../useUrlEncode/useUrlEncode.js");var B=require("../utils.js");function L(e){return e&&e.__esModule?e:{default:e}}var u=L(y);function P(e,t,i,l){const{parse:s,stringify:o}=b.useUrlEncode(e);const{state:f,getState:a,setState:r}=_.useSharedState(e,()=>i?.({parse:s})||e);const d=u.default.useRef(void 0);T.useInsertionEffect(()=>{const n=()=>{const p=s(B.filterUnknownParamsClient(e,I()));r(p)};window.addEventListener(q,n);return()=>{window.removeEventListener(q,n);clearTimeout(d.current)}},[r]);const w=u.default.useRef([]);const h=u.default.useCallback((n,p)=>{const S=typeof n==="function"?n(a()):{...a(),...n};const v=o(S,C(e));const U=M(window.location.pathname,l);const m=`${U}${v.length?"?":""}${v}${window.location.hash}`;const $=`${U}${window.location.search}${window.location.hash}`;if(m===$)return;r(S);const{replace:g,...k}=p||{};w.current.push([g?"replace":"push",m,k]);clearTimeout(d.current);const c=w.current.filter(Boolean).at(-1);if(c){queueMicrotask(()=>{d.current=setTimeout(()=>{w.current=[];t[c[0]](c[1],c[2])},R.TIMEOUT)})}},[t,o,a]);const E=u.default.useCallback(n=>{r(e);h(e,n)},[h,r]);return{updateState:r,updateUrl:h,state:f,reset:E,getState:a}}function C(e){const t=Object.keys(e);const i=window.location.search;const l=new URLSearchParams(i);const s=new URLSearchParams;for(const[o,f]of l){!t.includes(o)&&s.set(o,f)}return s}const q="popstate";function I(){return typeof window!=="undefined"&&window.location.search||""}function M(e,t){if(!t||t==="/"){return e}return e.slice(t.length)}exports.useUrlStateBase=P;
|
package/dist/utils.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export type UnknownObj = object | {
|
|
|
22
22
|
[key: string]: unknown;
|
|
23
23
|
};
|
|
24
24
|
export declare const isEqual: (val1: unknown, val2: unknown) => boolean;
|
|
25
|
-
export declare function filterUnknownParamsClient<T extends object>(shape: T, params
|
|
25
|
+
export declare function filterUnknownParamsClient<T extends object>(shape: T, params?: string | URLSearchParams | Record<string, string> | object): string;
|
|
26
26
|
export declare function filterUnknownParams<T extends object>(shape: T, searchParams?: object): T;
|
|
27
27
|
export declare function filterUnknown<T extends object>(shape: T, entries: [key: string, value: string][]): string[][];
|
|
28
28
|
export declare function assignValue<T extends object>(shape: T, newVal: Partial<T>): T;
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const c=n=>{const t=typeof n;const r=n===null;const e=Array.isArray(n);const s=n instanceof Date;const o=!r&&!s&&!e&&t==="object";return r&&"null"||s&&"date"||e&&"array"||o&&"object"||t};const a=typeof window==="undefined";const f=n=>new URLSearchParams(typeof n==="string"?l(n):n?.toString?.()||"");const l=n=>n.split("?")?.[1]||n||"";const u=(n,t)=>JSON.stringify(n)===JSON.stringify(t);function w(n,t){const r=new URLSearchParams;const e=i(n,[...new URLSearchParams(t||"").entries()]);for(const[s,o]of e){r.set(s,o)}return r.toString()}function y(n,t){return Object.fromEntries(i(n,Object.entries(t||{})))}function i(n,t){const r=Object.keys(n);const e=[];for(let s=0;s<t.length;s++){if(r.includes(t[s]?.[0])){e.push([t[s][0].replace(/\+/g," "),t[s][1]])}}return e}function S(n,t){const r=Object.assign({},n);for(const[e]of Object.entries(n)){const s=e;const o=t[s]!==void 0;r[s]=o?t[s]:n[s]}return r}const g={push:n=>{window&&window.history.pushState(null,"",n)},replace:n=>{window&&window.history.replaceState(null,"",n)}};const p=/apple/i.test(!a&&navigator?.userAgent||"");exports.assignValue=S;exports.filterUnknown=i;exports.filterUnknownParams=y;exports.filterUnknownParamsClient=w;exports.getParams=f;exports.isEqual=u;exports.isSSR=a;exports.isSafari=p;exports.routerHistory=g;exports.typeOf=c;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "state-in-url",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "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
|
|
3
|
+
"version": "5.1.0",
|
|
4
|
+
"description": "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.",
|
|
5
5
|
"homepage": "https://state-in-url.dev",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -30,48 +30,64 @@
|
|
|
30
30
|
"packages/example-nextjs14",
|
|
31
31
|
"packages/example-nextjs15",
|
|
32
32
|
"packages/example-react",
|
|
33
|
-
"packages/example-react-router6"
|
|
33
|
+
"packages/example-react-router6",
|
|
34
|
+
"packages/example-remix2"
|
|
34
35
|
],
|
|
35
36
|
"files": [
|
|
36
37
|
"dist"
|
|
37
38
|
],
|
|
38
|
-
"main": "dist/index.
|
|
39
|
+
"main": "./dist/index.js",
|
|
40
|
+
"module": "dist/index.mjs",
|
|
39
41
|
"exports": {
|
|
40
42
|
".": {
|
|
41
43
|
"types": "./dist/index.d.ts",
|
|
42
|
-
"default": "./dist/index.mjs"
|
|
44
|
+
"default": "./dist/index.mjs",
|
|
45
|
+
"require": "./dist/index.js"
|
|
43
46
|
},
|
|
44
47
|
"./next": {
|
|
45
48
|
"types": "./dist/next/index.d.ts",
|
|
46
|
-
"default": "./dist/next/index.mjs"
|
|
49
|
+
"default": "./dist/next/index.mjs",
|
|
50
|
+
"require": "./dist/next/index.js"
|
|
47
51
|
},
|
|
48
52
|
"./react-router": {
|
|
49
53
|
"types": "./dist/react-router/index.d.ts",
|
|
50
|
-
"default": "./dist/react-router/index.mjs"
|
|
54
|
+
"default": "./dist/react-router/index.mjs",
|
|
55
|
+
"require": "./dist/react-router/index.js"
|
|
56
|
+
},
|
|
57
|
+
"./remix": {
|
|
58
|
+
"types": "./dist/remix/index.d.ts",
|
|
59
|
+
"default": "./dist/remix/index.mjs",
|
|
60
|
+
"require": "./dist/remix/index.js"
|
|
51
61
|
},
|
|
52
62
|
"./encodeState": {
|
|
53
63
|
"types": "./dist/encodeState/index.d.ts",
|
|
54
|
-
"default": "./dist/encodeState/index.mjs"
|
|
64
|
+
"default": "./dist/encodeState/index.mjs",
|
|
65
|
+
"require": "./dist/encodeState/index.js"
|
|
55
66
|
},
|
|
56
67
|
"./encoder": {
|
|
57
68
|
"types": "./dist/encoder/index.d.ts",
|
|
58
|
-
"default": "./dist/encoder/index.mjs"
|
|
69
|
+
"default": "./dist/encoder/index.mjs",
|
|
70
|
+
"require": "./dist/encoder/index.js"
|
|
59
71
|
},
|
|
60
72
|
"./useSharedState": {
|
|
61
73
|
"types": "./dist/useSharedState/index.d.ts",
|
|
62
|
-
"default": "./dist/useSharedState/index.mjs"
|
|
74
|
+
"default": "./dist/useSharedState/index.mjs",
|
|
75
|
+
"require": "./dist/useSharedState/index.js"
|
|
63
76
|
},
|
|
64
77
|
"./useUrlEncode": {
|
|
65
78
|
"types": "./dist/useUrlEncode/index.d.ts",
|
|
66
|
-
"default": "./dist/useUrlEncode/index.mjs"
|
|
79
|
+
"default": "./dist/useUrlEncode/index.mjs",
|
|
80
|
+
"require": "./dist/useUrlEncode/index.js"
|
|
67
81
|
},
|
|
68
82
|
"./useUrlStateBase": {
|
|
69
83
|
"types": "./dist/useUrlStateBase/index.d.ts",
|
|
70
|
-
"default": "./dist/useUrlStateBase/index.mjs"
|
|
84
|
+
"default": "./dist/useUrlStateBase/index.mjs",
|
|
85
|
+
"require": "./dist/useUrlStateBase/index.js"
|
|
71
86
|
},
|
|
72
87
|
"./utils": {
|
|
73
88
|
"types": "./dist/utils.d.ts",
|
|
74
|
-
"default": "./dist/utils.mjs"
|
|
89
|
+
"default": "./dist/utils.mjs",
|
|
90
|
+
"require": "./dist/utils.js"
|
|
75
91
|
}
|
|
76
92
|
},
|
|
77
93
|
"types": "./dist/index.d.ts",
|
|
@@ -80,11 +96,14 @@
|
|
|
80
96
|
"test:int": "wireit",
|
|
81
97
|
"test:int:ci": "wireit",
|
|
82
98
|
"test:exports": "npm run build && npx babel-node --extensions .js,.mjs,.ts,.mts --config-file ./babel.config.json -- ./packages/urlstate/exportsTest.ts",
|
|
99
|
+
"install:all": "npm install",
|
|
100
|
+
"install:ci": "npm ci",
|
|
83
101
|
"test": "wireit",
|
|
84
102
|
"tsc": "wireit",
|
|
85
103
|
"dev": "wireit",
|
|
86
104
|
"dev:lib": "wireit",
|
|
87
105
|
"dev:nextjs14": "wireit",
|
|
106
|
+
"dev:remix2": "wireit",
|
|
88
107
|
"bump": "npx standard-version --no-verify",
|
|
89
108
|
"build": "wireit",
|
|
90
109
|
"build:demo": "wireit",
|
|
@@ -99,7 +118,7 @@
|
|
|
99
118
|
"kill-vite": "wireit",
|
|
100
119
|
"kill": "wireit",
|
|
101
120
|
"rmdist": "rm -rf dist",
|
|
102
|
-
"cleanup": "rm -rf dist .wireit node_modules test-results playwright-report coverage-reports nyc_coverage packages/example-nextjs14/node_modules packages/example-nextjs14/.next packages/example-nextjs15/node_modules packages/example-nextjs15/.next packages/example-react/node_modules packages/example-react-router6/node_modules",
|
|
121
|
+
"cleanup": "rm -rf dist .wireit node_modules test-results playwright-report coverage-reports nyc_coverage packages/example-nextjs14/node_modules packages/example-nextjs14/.next packages/example-nextjs15/node_modules packages/example-nextjs15/.next packages/example-react/node_modules packages/example-react-router6/node_modules packages/example-remix2/node_modules",
|
|
103
122
|
"reinstall": "npm run cleanup && npm install",
|
|
104
123
|
"setup": "playwright install --with-deps",
|
|
105
124
|
"prepack": "npm run build && cp package.json dist/package.json && npm run build:demo",
|
|
@@ -151,6 +170,7 @@
|
|
|
151
170
|
"dependencies": [
|
|
152
171
|
"dev:lib",
|
|
153
172
|
"dev:react",
|
|
173
|
+
"dev:remix2",
|
|
154
174
|
"dev:router6",
|
|
155
175
|
"dev:nextjs15"
|
|
156
176
|
],
|
|
@@ -176,6 +196,10 @@
|
|
|
176
196
|
"command": "cd packages/example-react-router6 && npm run dev",
|
|
177
197
|
"service": true
|
|
178
198
|
},
|
|
199
|
+
"dev:remix2": {
|
|
200
|
+
"command": "cd packages/example-remix2 && PORT=3003 npm run dev",
|
|
201
|
+
"service": true
|
|
202
|
+
},
|
|
179
203
|
"dev:nextjs14": {
|
|
180
204
|
"command": "cd packages/example-nextjs14 && npm run dev --turbo",
|
|
181
205
|
"service": true
|
|
@@ -196,6 +220,12 @@
|
|
|
196
220
|
"build"
|
|
197
221
|
]
|
|
198
222
|
},
|
|
223
|
+
"build:remix2": {
|
|
224
|
+
"command": "cd packages/example-remix2 && npm run build",
|
|
225
|
+
"dependencies": [
|
|
226
|
+
"build"
|
|
227
|
+
]
|
|
228
|
+
},
|
|
199
229
|
"build:demo": {
|
|
200
230
|
"dependencies": [
|
|
201
231
|
"build"
|
|
@@ -241,6 +271,17 @@
|
|
|
241
271
|
"command": "npx vite preview --port 5181 packages/example-react-router6",
|
|
242
272
|
"service": true
|
|
243
273
|
},
|
|
274
|
+
"start:remix2": {
|
|
275
|
+
"command": "cd packages/example-remix2 && npm run start",
|
|
276
|
+
"dependencies": [
|
|
277
|
+
"build:remix2"
|
|
278
|
+
],
|
|
279
|
+
"service": true
|
|
280
|
+
},
|
|
281
|
+
"start:remix2:ci": {
|
|
282
|
+
"command": "cd packages/example-remix2 && npm run start",
|
|
283
|
+
"service": true
|
|
284
|
+
},
|
|
244
285
|
"start:demo15": {
|
|
245
286
|
"dependencies": [
|
|
246
287
|
"build:next15"
|
|
@@ -257,7 +298,8 @@
|
|
|
257
298
|
"dependencies": [
|
|
258
299
|
"start:demo",
|
|
259
300
|
"start:react",
|
|
260
|
-
"start:router6"
|
|
301
|
+
"start:router6",
|
|
302
|
+
"start:remix2"
|
|
261
303
|
],
|
|
262
304
|
"service": true
|
|
263
305
|
},
|
|
@@ -266,7 +308,8 @@
|
|
|
266
308
|
"dependencies": [
|
|
267
309
|
"start:demo:ci",
|
|
268
310
|
"start:react:ci",
|
|
269
|
-
"start:router6:ci"
|
|
311
|
+
"start:router6:ci",
|
|
312
|
+
"start:remix2:ci"
|
|
270
313
|
],
|
|
271
314
|
"service": true
|
|
272
315
|
},
|
|
@@ -280,7 +323,8 @@
|
|
|
280
323
|
"build:react",
|
|
281
324
|
"build:demo:tests",
|
|
282
325
|
"build:next15",
|
|
283
|
-
"build:router6"
|
|
326
|
+
"build:router6",
|
|
327
|
+
"build:remix2"
|
|
284
328
|
]
|
|
285
329
|
},
|
|
286
330
|
"build:react": {
|
|
@@ -404,6 +448,8 @@
|
|
|
404
448
|
"decode",
|
|
405
449
|
"Next.js",
|
|
406
450
|
"react-router",
|
|
451
|
+
"remix",
|
|
452
|
+
"remixjs",
|
|
407
453
|
"url",
|
|
408
454
|
"url synchronization",
|
|
409
455
|
"url sync",
|