clear-react-router 1.7.9 → 1.8.1
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 +84 -20
- package/dist/cell.d.ts +2 -3
- package/dist/components/Link.d.ts +1 -1
- package/dist/components/Router.d.ts +2 -2
- package/dist/config/routerConfig.d.ts +2 -1
- package/dist/constants.d.ts +1 -1
- package/dist/{state/createState.d.ts → create.d.ts} +1 -2
- package/dist/hooks/useAction.d.ts +1 -6
- package/dist/hooks/useBlocker.d.ts +1 -1
- package/dist/hooks/useInvalidate.d.ts +1 -2
- package/dist/hooks/useLoaderState.d.ts +1 -1
- package/dist/hooks/useNavigate.d.ts +1 -2
- package/dist/hooks/useQueryParam.d.ts +2 -2
- package/dist/hooks/useSetInitialContext.d.ts +2 -1
- package/dist/hooks/useSetRouterConfig.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +450 -387
- package/dist/instance.d.ts +1 -0
- package/dist/runtime/invalidate.d.ts +2 -6
- package/dist/runtime/navigate.d.ts +2 -2
- package/dist/runtime/prefetch.d.ts +2 -1
- package/dist/{types/global.d.ts → types.d.ts} +62 -6
- package/dist/utils/adapter.d.ts +2 -2
- package/dist/utils/commitNavigation.d.ts +3 -2
- package/dist/utils/commitState.d.ts +2 -2
- package/dist/utils/createRouterInstance.d.ts +2 -0
- package/dist/utils/findRoute.d.ts +1 -1
- package/dist/utils/isCacheItemFresh.d.ts +2 -2
- package/dist/utils/renderElement.d.ts +1 -1
- package/dist/utils/revalidateCache.d.ts +2 -3
- package/dist/utils/utils.d.ts +1 -1
- package/package.json +1 -1
- package/dist/hooks/useGetAction.d.ts +0 -4
- package/dist/state/state.d.ts +0 -50
- package/dist/utils/getContext.d.ts +0 -4
package/README.md
CHANGED
|
@@ -38,23 +38,6 @@ It provides first-class support for:
|
|
|
38
38
|
|
|
39
39
|
## API
|
|
40
40
|
|
|
41
|
-
### `createRouter(routes)`
|
|
42
|
-
|
|
43
|
-
Normalizes route configuration. Handles wildcard `*` routes, extracts dynamic params, builds nested paths.
|
|
44
|
-
|
|
45
|
-
| Property | Type | Description |
|
|
46
|
-
|----------|------|-------------|
|
|
47
|
-
| `path` | `string` | Route path, e.g., `/user/:userId` |
|
|
48
|
-
| `element` | `ReactElement \| () => ReactElement \| LazyComponent` | Component to render |
|
|
49
|
-
| `beforeLoad` | `({ params, context, redirect, setContext }) => Promise<unknown> \| undefined \| void` | Auth checks and redirects. Can update context via `setContext`. `redirect` is provided by the router |
|
|
50
|
-
| `loader` | `({ params, context, setContext }) => Promise<unknown>` | Fetch data using route params and context. Can update context via `setContext` |
|
|
51
|
-
| `afterLoad` | `({ params, context, setContext }) => Promise<void>` | Analytics, side effects after data is loaded. Can update context via `setContext` |
|
|
52
|
-
| `fallback` | `ReactElement \| () => ReactElement` | Loading fallback (for lazy loading) |
|
|
53
|
-
| `loaderFallback` | `ReactElement \| () => ReactElement` | Loading fallback for the route's `loader`. Overrides the global `defaultLoaderFallback` set in `Router` |
|
|
54
|
-
| `errorElement` | `ReactElement \| () => ReactElement` | Error fallback for the route. Overrides the global `defaultErrorElement` set in `Router` |
|
|
55
|
-
| `staleTime` | `number` | Time in ms before cached data is considered stale and re-fetched in the background. If not provided, data never expires (cached forever) |
|
|
56
|
-
| `actions` | `({ params, context, invalidate, setContext }) => Record<string, (formData: FormData) => unknown \| Promise<unknown>>` | Defines route actions for data mutations. Actions receive `FormData`, can update context via `setContext`, and can refresh loader data using the router-provided `invalidate`. |
|
|
57
|
-
|
|
58
41
|
### `Router`
|
|
59
42
|
|
|
60
43
|
| Prop | Type | Default | Description |
|
|
@@ -64,6 +47,7 @@ Normalizes route configuration. Handles wildcard `*` routes, extracts dynamic pa
|
|
|
64
47
|
| `animationDuration` | `number` | `optional` | Animation duration in milliseconds (browser default is used if not set) |
|
|
65
48
|
| `defaultLoaderFallback` | `ReactElement \| () => ReactElement` | `optional` | Default loading fallback for every route loader |
|
|
66
49
|
| `defaultErrorElement` | `ReactElement \| () => ReactElement` | `optional` | Default error fallback for every route |
|
|
50
|
+
| `defaultRetry` | `number \| { count: number; delay: number }` | `optional` | Default cache revalidation retry policy for all routes |
|
|
67
51
|
| `beforeLoad` | `({ params, context, redirect, setContext }) => Promise<unknown> \| undefined \| void` | `undefined` | Runs before every navigation. Useful for authentication, analytics, or updating shared context. |
|
|
68
52
|
| `afterLoad` | `({ params, context, setContext }) => Promise<void>` | `undefined` | Runs after every successful navigation. Useful for analytics, page tracking, or other global side effects. |
|
|
69
53
|
| `spinner` | `boolean \| undefined` | `true` | Show a small spinner in the corner while loading data (only when `isAnimated` is enabled) |
|
|
@@ -82,9 +66,26 @@ Normalizes route configuration. Handles wildcard `*` routes, extracts dynamic pa
|
|
|
82
66
|
<Router routes={routes} spinner={false} isAnimated /> {/* disable the spinner */}
|
|
83
67
|
</div>
|
|
84
68
|
```
|
|
85
|
-
|
|
86
69
|
> **Note:** When `isAnimated` is enabled, `loaderFallback` is not shown. Instead, a small spinner appears (if `spinner={true}`). On the initial page load, however, the route's loaderFallback is rendered if available.
|
|
87
70
|
|
|
71
|
+
### `createRouter(routes)`
|
|
72
|
+
|
|
73
|
+
Normalizes route configuration. Handles wildcard `*` routes, extracts dynamic params, builds nested paths.
|
|
74
|
+
|
|
75
|
+
| Property | Type | Description |
|
|
76
|
+
|----------|------|-------------|
|
|
77
|
+
| `path` | `string` | Route path, e.g., `/user/:userId` |
|
|
78
|
+
| `element` | `ReactElement \| () => ReactElement \| LazyComponent` | Component to render |
|
|
79
|
+
| `beforeLoad` | `({ params, context, redirect, setContext }) => Promise<unknown> \| undefined \| void` | Auth checks and redirects. Can update context via `setContext`. `redirect` is provided by the router |
|
|
80
|
+
| `loader` | `({ params, context, setContext }) => Promise<unknown>` | Fetch data using route params and context. Can update context via `setContext` |
|
|
81
|
+
| `afterLoad` | `({ params, context, setContext }) => Promise<void>` | Analytics, side effects after data is loaded. Can update context via `setContext` |
|
|
82
|
+
| `fallback` | `ReactElement \| () => ReactElement` | Loading fallback (for lazy loading) |
|
|
83
|
+
| `loaderFallback` | `ReactElement \| () => ReactElement` | Loading fallback for the route's `loader`. Overrides the global `defaultLoaderFallback` set in `Router` |
|
|
84
|
+
| `retry` | `number \| { count: number; delay: number }` | `optional` | Overrides the global cache revalidation retry policy for this route |
|
|
85
|
+
| `errorElement` | `ReactElement \| () => ReactElement` | Error fallback for the route. Overrides the global `defaultErrorElement` set in `Router` |
|
|
86
|
+
| `staleTime` | `number` | Time in ms before cached data is considered stale and re-fetched in the background. If not provided, data never expires (cached forever) |
|
|
87
|
+
| `actions` | `({ params, context, invalidate, setContext }) => Record<string, (formData: FormData) => unknown \| Promise<unknown>>` | Defines route actions for data mutations. Actions receive `FormData`, can update context via `setContext`, and can refresh loader data using the router-provided `invalidate`. |
|
|
88
|
+
|
|
88
89
|
### `Link`
|
|
89
90
|
|
|
90
91
|
Component for client-side navigation with prefetch support.
|
|
@@ -125,6 +126,68 @@ import { Router, Link } from 'clear-react-router';
|
|
|
125
126
|
```
|
|
126
127
|
**Important**: prefetch="render" should be used sparingly, as it preloads data immediately when the link is rendered, which may cause unnecessary network requests.
|
|
127
128
|
|
|
129
|
+
## Retry
|
|
130
|
+
|
|
131
|
+
Sometimes a request may fail because of a temporary network issue or a short-lived server problem. Instead of immediately rendering the error state, you can configure the router to automatically retry loading route data.
|
|
132
|
+
|
|
133
|
+
### Route-level retry
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
{
|
|
137
|
+
path: '/posts',
|
|
138
|
+
loader: loadPosts,
|
|
139
|
+
retry: 3,
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`retry: 3` means the router will make up to **3 additional attempts** after the initial failed request (up to **4 attempts** in total).
|
|
144
|
+
|
|
145
|
+
You can also specify a delay between attempts:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
{
|
|
149
|
+
path: '/posts',
|
|
150
|
+
loader: loadPosts,
|
|
151
|
+
retry: {
|
|
152
|
+
count: 3,
|
|
153
|
+
delay: 500,
|
|
154
|
+
},
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Global retry
|
|
159
|
+
|
|
160
|
+
To apply the same retry policy to all routes, use `defaultRetry`:
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
<Router routes={routes} defaultRetry={2} />
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
or with a delay:
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
<Router routes={routes} defaultRetry={{ count: 2, delay: 500 }} />
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
A route-level `retry` always overrides `defaultRetry`.
|
|
173
|
+
|
|
174
|
+
### How it works
|
|
175
|
+
|
|
176
|
+
Unlike many routing libraries, retry is **not limited to the initial loader execution**.
|
|
177
|
+
|
|
178
|
+
The retry policy is applied to the router's **cache revalidation mechanism**, so it automatically works for every operation that reloads route data, including:
|
|
179
|
+
|
|
180
|
+
* Initial route loading
|
|
181
|
+
* Cache revalidation
|
|
182
|
+
* `invalidate()`
|
|
183
|
+
* `prefetch()`
|
|
184
|
+
|
|
185
|
+
This ensures consistent behavior regardless of how the data is being refreshed.
|
|
186
|
+
|
|
187
|
+
### Why?
|
|
188
|
+
|
|
189
|
+
The router treats the route loader as the single source of truth for route data. Since every data refresh goes through the same cache revalidation pipeline, retry is configured once and automatically applies everywhere without any additional code.
|
|
190
|
+
|
|
128
191
|
### `redirect`
|
|
129
192
|
|
|
130
193
|
Function provided to `beforeLoad` for programmatic redirection.
|
|
@@ -456,10 +519,11 @@ await invalidate('/post/[id]/comment/[id]');
|
|
|
456
519
|
|
|
457
520
|
#### Including child routes
|
|
458
521
|
|
|
459
|
-
To revalidate
|
|
522
|
+
To revalidate routes together with their cached child routes, pass the `withChildren` option:
|
|
460
523
|
|
|
461
524
|
```tsx
|
|
462
|
-
await invalidate('/posts', { withChildren: true });
|
|
525
|
+
await invalidate('/posts', { withChildren: true });
|
|
526
|
+
await invalidate(['/posts', '/users'], { withChildren: true });
|
|
463
527
|
```
|
|
464
528
|
|
|
465
529
|
This will recursively revalidate cached routes inside the route tree.
|
package/dist/cell.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
declare class Cell<T> {
|
|
1
|
+
export declare class Cell<T> {
|
|
2
2
|
private _value;
|
|
3
3
|
constructor(_value: T);
|
|
4
4
|
get value(): T;
|
|
5
5
|
set(action: T | ((prev: T) => T)): void;
|
|
6
6
|
}
|
|
7
|
-
export declare const loaderStateRef: Cell<import("./types
|
|
7
|
+
export declare const loaderStateRef: Cell<import("./types").LoaderState>;
|
|
8
8
|
export declare const prevPathnameRef: Cell<string>;
|
|
9
9
|
export declare const timestampMap: Map<string, number>;
|
|
10
|
-
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RouterProps } from '../types
|
|
2
|
-
export declare const Router: ({ routes, beforeLoad, afterLoad, animationDuration, isAnimated, spinner, preserveScroll, showFallbackOnAnimation, prefetch, hoverPrefetchDelay, errorBoundary: ErrorBoundary, context: initialContext, defaultLoaderFallback, defaultErrorElement, }: RouterProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
1
|
+
import { RouterProps } from '../types';
|
|
2
|
+
export declare const Router: ({ routes, beforeLoad, afterLoad, animationDuration, isAnimated, spinner, preserveScroll, showFallbackOnAnimation, prefetch, hoverPrefetchDelay, errorBoundary: ErrorBoundary, context: initialContext, defaultLoaderFallback, defaultErrorElement, defaultRetry, }: RouterProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ClientRouteItem, RouterProps } from '../types
|
|
1
|
+
import { ClientRouteItem, RouterProps } from '../types';
|
|
2
2
|
declare class RouterConfig {
|
|
3
3
|
routes: RouterProps['routes'];
|
|
4
4
|
prefetch: RouterProps['prefetch'];
|
|
@@ -7,6 +7,7 @@ declare class RouterConfig {
|
|
|
7
7
|
hoverPrefetchDelay: number;
|
|
8
8
|
beforeLoad?: ClientRouteItem['beforeLoad'];
|
|
9
9
|
afterLoad?: ClientRouteItem['afterLoad'];
|
|
10
|
+
defaultRetry?: RouterProps['defaultRetry'];
|
|
10
11
|
configure(config: Partial<RouterConfig>): void;
|
|
11
12
|
}
|
|
12
13
|
export declare const routerConfig: RouterConfig;
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
type SetStateAction<T> = ((prevState: T) => T) | T;
|
|
2
2
|
type Listener<T> = (state: T, prevState: T) => void;
|
|
3
|
-
type Store<T> = {
|
|
3
|
+
export type Store<T> = {
|
|
4
4
|
subscribe: (listener: Listener<T>) => () => void;
|
|
5
5
|
getState: () => T;
|
|
6
6
|
setState: (action: SetStateAction<T>) => void;
|
|
7
7
|
};
|
|
8
8
|
export declare const create: <T>(initialState: T) => Store<T>;
|
|
9
9
|
export declare const useGlobalState: <T>({ subscribe, getState, setState }: Store<T>) => readonly [T, (action: SetStateAction<T>) => void];
|
|
10
|
-
export declare const createState: <T>(initialState: T) => () => readonly [T, (action: SetStateAction<T>) => void];
|
|
11
10
|
export {};
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
onSuccess: (args: unknown) => void;
|
|
3
|
-
onError: (args: unknown) => void;
|
|
4
|
-
}> | undefined;
|
|
5
|
-
export declare const useAction: (action: string, options?: Options) => (formData: FormData) => Promise<void>;
|
|
6
|
-
export {};
|
|
1
|
+
export declare const useAction: (action: string, options?: import("../types").Options) => (arg: FormData) => Promise<void>;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const useInvalidate: () => typeof invalidate;
|
|
1
|
+
export declare const useInvalidate: () => (pathList?: string | string[], options?: import("../types").InvalidateOptions) => Promise<void>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { LoaderState } from '../types
|
|
1
|
+
import { LoaderState } from '../types';
|
|
2
2
|
export declare const useLoaderState: <T>() => LoaderState<T>;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const useNavigate: () => (arg: Location | string | -1) => Promise<void>;
|
|
1
|
+
export declare const useNavigate: () => (arg: import("..").Location | string | -1) => Promise<void>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function useQueryParam<T>(field: string, adapter:
|
|
1
|
+
import { Adapter } from '../types';
|
|
2
|
+
export declare function useQueryParam<T>(field: string, adapter: Adapter<T>, defaultValue?: T): [T, (arg: T | null) => void];
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { RouterProps } from '../types';
|
|
2
|
+
export declare const useSetInitialContext: (initialContext?: RouterProps["context"]) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RouterProps } from '../types
|
|
1
|
+
import { RouterProps } from '../types';
|
|
2
2
|
export declare const useSetRouterConfig: (routerProps: RouterProps) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -14,4 +14,4 @@ export { useSearchParams } from './hooks/useSearchParams';
|
|
|
14
14
|
export { useFormContext } from './hooks/useFormContext';
|
|
15
15
|
export { adapter } from './utils/adapter';
|
|
16
16
|
export { createRouter } from './utils/utils';
|
|
17
|
-
export type { RouteItem, BlockerState, Location,
|
|
17
|
+
export type { RouteItem, BlockerState, Location, Adapter, RouterProps } from './types';
|