clear-react-router 1.3.7 → 1.3.9
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Dispatch, SetStateAction } from 'react';
|
|
2
|
-
import { BlockerState, Location, RouteItem, UpdateBlockedRouteProps } from '../types/global';
|
|
2
|
+
import { BlockerState, LoaderState, Location, RouteItem, UpdateBlockedRouteProps } from '../types/global';
|
|
3
3
|
export type PropsContextValue = {
|
|
4
4
|
routeList: RouteItem[];
|
|
5
5
|
isAnimated: boolean;
|
|
@@ -8,7 +8,6 @@ export type NavigationContextValue = {
|
|
|
8
8
|
location: Location;
|
|
9
9
|
blockerState: BlockerState;
|
|
10
10
|
isLoading: boolean;
|
|
11
|
-
shouldErrorElementShown: boolean;
|
|
12
11
|
};
|
|
13
12
|
export type ActionsContextValue = {
|
|
14
13
|
setLocation: Dispatch<SetStateAction<Location>>;
|
|
@@ -18,7 +17,7 @@ export type ActionsContextValue = {
|
|
|
18
17
|
setContext(arg: object): void;
|
|
19
18
|
};
|
|
20
19
|
export type DataContextValue = {
|
|
21
|
-
|
|
20
|
+
loaderState: LoaderState;
|
|
22
21
|
context: Record<string, unknown>;
|
|
23
22
|
};
|
|
24
23
|
export declare const PropsContext: import("react").Context<PropsContextValue>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Dispatch, type SetStateAction } from 'react';
|
|
2
|
-
import type { BlockerState, Location, RevalidateCacheArgs, RouteItem, UpdateBlockedRouteProps } from '../types/global';
|
|
2
|
+
import type { BlockerState, LoaderState, Location, RevalidateCacheArgs, RouteItem, UpdateBlockedRouteProps } from '../types/global';
|
|
3
3
|
type UseHandleNavigation = {
|
|
4
4
|
routeList: RouteItem[];
|
|
5
5
|
setLocation: (arg: Location) => void;
|
|
@@ -8,11 +8,11 @@ type UseHandleNavigation = {
|
|
|
8
8
|
isAnimated: boolean;
|
|
9
9
|
setContext: Dispatch<SetStateAction<Record<string, unknown>>>;
|
|
10
10
|
setScrollMap: Dispatch<SetStateAction<Record<string, number>>>;
|
|
11
|
+
setLoaderState: Dispatch<SetStateAction<LoaderState>>;
|
|
11
12
|
};
|
|
12
|
-
export declare const useHandleNavigation: ({ setLocation, routeList, context, revalidateCache, isAnimated, setContext, setScrollMap, }: UseHandleNavigation) => {
|
|
13
|
+
export declare const useHandleNavigation: ({ setLocation, routeList, context, revalidateCache, isAnimated, setContext, setScrollMap, setLoaderState, }: UseHandleNavigation) => {
|
|
13
14
|
blockerState: BlockerState;
|
|
14
15
|
updateLocation: (nextLocation: Location) => Promise<void>;
|
|
15
16
|
updateBlockedRoute: ({ type, payload }: UpdateBlockedRouteProps) => void;
|
|
16
|
-
beforeLoadError: boolean;
|
|
17
17
|
};
|
|
18
18
|
export {};
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { type Dispatch, type SetStateAction } from 'react';
|
|
2
|
-
import type { RevalidateCacheArgs, RouteItem } from '../types/global';
|
|
2
|
+
import type { LoaderState, RevalidateCacheArgs, RouteItem } from '../types/global';
|
|
3
3
|
type UseLoaderParams = {
|
|
4
4
|
routeList: RouteItem[];
|
|
5
5
|
context: Record<string, unknown>;
|
|
6
6
|
setContext: Dispatch<SetStateAction<Record<string, unknown>>>;
|
|
7
|
+
setLoaderState: Dispatch<SetStateAction<LoaderState>>;
|
|
7
8
|
};
|
|
8
|
-
export declare const useLoader: ({ routeList, context, setContext }: UseLoaderParams) => {
|
|
9
|
-
loaderCache: unknown;
|
|
10
|
-
loaderError: boolean;
|
|
9
|
+
export declare const useLoader: ({ routeList, context, setContext, setLoaderState }: UseLoaderParams) => {
|
|
11
10
|
prefetchLoader: (pathname: string) => Promise<void>;
|
|
12
11
|
revalidateCache: ({ routeItem, isCurrentRoute, pathname }: RevalidateCacheArgs) => Promise<void>;
|
|
13
12
|
isLoading: boolean;
|
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ var require_react_jsx_runtime_production = /* @__PURE__ */ __commonJSMin(((expor
|
|
|
45
45
|
var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
46
46
|
module.exports = require_react_jsx_runtime_production();
|
|
47
47
|
})))();
|
|
48
|
-
var Provider = ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader,
|
|
48
|
+
var Provider = ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader, loaderState, blockerState, routeList, isLoading, isAnimated }) => {
|
|
49
49
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PropsContext.Provider, {
|
|
50
50
|
value: {
|
|
51
51
|
routeList,
|
|
@@ -62,13 +62,12 @@ var Provider = ({ children, setContext, context, updateBlockedRoute, updateLocat
|
|
|
62
62
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DataContext.Provider, {
|
|
63
63
|
value: {
|
|
64
64
|
context,
|
|
65
|
-
|
|
65
|
+
loaderState
|
|
66
66
|
},
|
|
67
67
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavigationContext.Provider, {
|
|
68
68
|
value: {
|
|
69
69
|
blockerState,
|
|
70
70
|
location,
|
|
71
|
-
shouldErrorElementShown,
|
|
72
71
|
isLoading
|
|
73
72
|
},
|
|
74
73
|
children
|
|
@@ -139,12 +138,11 @@ var comparePaths = (el, pathname) => {
|
|
|
139
138
|
};
|
|
140
139
|
//#endregion
|
|
141
140
|
//#region hooks/useHandleNavigation.ts
|
|
142
|
-
var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, isAnimated, setContext, setScrollMap }) => {
|
|
141
|
+
var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, isAnimated, setContext, setScrollMap, setLoaderState }) => {
|
|
143
142
|
const [blockedRoute, setBlockedRoute] = useState({
|
|
144
143
|
from: "",
|
|
145
144
|
to: ""
|
|
146
145
|
});
|
|
147
|
-
const [beforeLoadError, setBeforeLoadError] = useState(false);
|
|
148
146
|
const prevPathname = useRef("");
|
|
149
147
|
const navigationSeq = useRef(0);
|
|
150
148
|
const updateScrollMap = useCallback(() => setScrollMap((prevState) => {
|
|
@@ -187,8 +185,21 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, i
|
|
|
187
185
|
params,
|
|
188
186
|
setContext
|
|
189
187
|
});
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
setLoaderState((prevState) => ({
|
|
189
|
+
...prevState,
|
|
190
|
+
[nextLocation.pathname]: {
|
|
191
|
+
...prevState[nextLocation.pathname],
|
|
192
|
+
beforeLoadError: null
|
|
193
|
+
}
|
|
194
|
+
}));
|
|
195
|
+
} catch (error) {
|
|
196
|
+
setLoaderState((prevState) => ({
|
|
197
|
+
...prevState,
|
|
198
|
+
[nextLocation.pathname]: {
|
|
199
|
+
...prevState[nextLocation.pathname],
|
|
200
|
+
beforeLoadError: error
|
|
201
|
+
}
|
|
202
|
+
}));
|
|
192
203
|
transitionedNavigation({
|
|
193
204
|
nextLocation,
|
|
194
205
|
isAnimated: false
|
|
@@ -207,7 +218,6 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, i
|
|
|
207
218
|
isFirstCall,
|
|
208
219
|
isAnimated
|
|
209
220
|
});
|
|
210
|
-
setBeforeLoadError(false);
|
|
211
221
|
if (nextItem?.afterLoad) await nextItem.afterLoad({
|
|
212
222
|
context,
|
|
213
223
|
params,
|
|
@@ -220,7 +230,8 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, i
|
|
|
220
230
|
transitionedNavigation,
|
|
221
231
|
isAnimated,
|
|
222
232
|
setContext,
|
|
223
|
-
updateScrollMap
|
|
233
|
+
updateScrollMap,
|
|
234
|
+
setLoaderState
|
|
224
235
|
]);
|
|
225
236
|
const setNextLocationRef = useLatest(navigationHandler);
|
|
226
237
|
const updateBlockedRoute = useCallback(({ type, payload = "" }) => setBlockedRoute((prevState) => {
|
|
@@ -273,18 +284,14 @@ var useHandleNavigation = ({ setLocation, routeList, context, revalidateCache, i
|
|
|
273
284
|
return "unblocked";
|
|
274
285
|
}, [blockedRoute]),
|
|
275
286
|
updateLocation,
|
|
276
|
-
updateBlockedRoute
|
|
277
|
-
beforeLoadError
|
|
287
|
+
updateBlockedRoute
|
|
278
288
|
};
|
|
279
289
|
};
|
|
280
290
|
//#endregion
|
|
281
291
|
//#region hooks/useLoader.ts
|
|
282
|
-
var useLoader = ({ routeList, context, setContext }) => {
|
|
283
|
-
const [loaderCache, setLoaderCache] = useState();
|
|
284
|
-
const [loaderError, setLoaderError] = useState(false);
|
|
292
|
+
var useLoader = ({ routeList, context, setContext, setLoaderState }) => {
|
|
285
293
|
const [isLoading, setIsLoading] = useState(false);
|
|
286
294
|
const cacheTimestampsRef = useRef({});
|
|
287
|
-
const loaderCacheRef = useRef({});
|
|
288
295
|
const isCacheItemFresh = useCallback(({ routeItem, pathname }) => {
|
|
289
296
|
if (!routeItem) return true;
|
|
290
297
|
const currentCacheTimestamp = cacheTimestampsRef.current[pathname];
|
|
@@ -294,21 +301,12 @@ var useLoader = ({ routeList, context, setContext }) => {
|
|
|
294
301
|
}, []);
|
|
295
302
|
const revalidateCache = useCallback(async ({ routeItem, isCurrentRoute, pathname }) => {
|
|
296
303
|
if (!routeItem?.loader) return;
|
|
297
|
-
if (isCacheItemFresh({
|
|
298
|
-
routeItem,
|
|
299
|
-
pathname
|
|
300
|
-
}) && isCurrentRoute) setLoaderCache(loaderCacheRef.current[pathname]);
|
|
301
304
|
if (isCacheItemFresh({
|
|
302
305
|
routeItem,
|
|
303
306
|
pathname
|
|
304
307
|
})) return;
|
|
305
308
|
if (isCurrentRoute) setIsLoading(true);
|
|
306
|
-
loaderCacheRef.current = Object.keys(loaderCacheRef.current).filter((el) => el !== routeItem.path).reduce((acc, cur) => ({
|
|
307
|
-
...acc,
|
|
308
|
-
[cur]: loaderCacheRef.current[cur]
|
|
309
|
-
}), {});
|
|
310
309
|
try {
|
|
311
|
-
if (isCurrentRoute) setLoaderError(false);
|
|
312
310
|
const params = getParamsObject({
|
|
313
311
|
routeItem,
|
|
314
312
|
pathname
|
|
@@ -322,13 +320,23 @@ var useLoader = ({ routeList, context, setContext }) => {
|
|
|
322
320
|
...cacheTimestampsRef.current,
|
|
323
321
|
[pathname]: Date.now()
|
|
324
322
|
};
|
|
325
|
-
|
|
326
|
-
...
|
|
327
|
-
[pathname]:
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
323
|
+
if (isCurrentRoute) setLoaderState((prevState) => ({
|
|
324
|
+
...prevState,
|
|
325
|
+
[pathname]: {
|
|
326
|
+
...prevState[pathname],
|
|
327
|
+
data: result,
|
|
328
|
+
loaderError: null
|
|
329
|
+
}
|
|
330
|
+
}));
|
|
331
|
+
} catch (error) {
|
|
332
|
+
if (isCurrentRoute) setLoaderState((prevState) => ({
|
|
333
|
+
...prevState,
|
|
334
|
+
[pathname]: {
|
|
335
|
+
...prevState[pathname],
|
|
336
|
+
data: null,
|
|
337
|
+
loaderError: error
|
|
338
|
+
}
|
|
339
|
+
}));
|
|
332
340
|
} finally {
|
|
333
341
|
if (isCurrentRoute) setIsLoading(false);
|
|
334
342
|
}
|
|
@@ -338,8 +346,6 @@ var useLoader = ({ routeList, context, setContext }) => {
|
|
|
338
346
|
setContext
|
|
339
347
|
]);
|
|
340
348
|
return {
|
|
341
|
-
loaderCache,
|
|
342
|
-
loaderError,
|
|
343
349
|
prefetchLoader: useCallback(async (pathname) => {
|
|
344
350
|
const item = routeList.find((el) => comparePaths(el, pathname));
|
|
345
351
|
if (item) await revalidateCache({
|
|
@@ -410,31 +416,34 @@ var useApplyCustomAnimation = (animationDuration) => {
|
|
|
410
416
|
var RouterProvider = ({ children, routeList, context: initialContext = {}, isAnimated = false, animationDuration, preserveScroll = true }) => {
|
|
411
417
|
const [location, setLocation] = useState({});
|
|
412
418
|
const [context, setContext] = useState(initialContext);
|
|
419
|
+
const [loaderState, setLoaderState] = useState({});
|
|
413
420
|
useApplyCustomAnimation(animationDuration);
|
|
414
421
|
const setScrollMap = usePreserveScroll({
|
|
415
422
|
pathname: location.pathname,
|
|
416
423
|
preserveScroll
|
|
417
424
|
});
|
|
418
|
-
const {
|
|
425
|
+
const { prefetchLoader, revalidateCache, isLoading } = useLoader({
|
|
419
426
|
routeList,
|
|
420
427
|
context,
|
|
421
|
-
setContext
|
|
428
|
+
setContext,
|
|
429
|
+
setLoaderState
|
|
422
430
|
});
|
|
423
|
-
const { blockerState, updateLocation, updateBlockedRoute
|
|
431
|
+
const { blockerState, updateLocation, updateBlockedRoute } = useHandleNavigation({
|
|
424
432
|
setLocation,
|
|
425
433
|
routeList,
|
|
426
434
|
context,
|
|
427
435
|
setContext,
|
|
428
436
|
revalidateCache,
|
|
429
437
|
isAnimated,
|
|
430
|
-
setScrollMap
|
|
438
|
+
setScrollMap,
|
|
439
|
+
setLoaderState
|
|
431
440
|
});
|
|
432
441
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Provider, {
|
|
433
442
|
...useMemo(() => ({
|
|
434
443
|
location,
|
|
435
444
|
setLocation,
|
|
436
445
|
updateLocation,
|
|
437
|
-
|
|
446
|
+
loaderState,
|
|
438
447
|
prefetchLoader,
|
|
439
448
|
updateBlockedRoute,
|
|
440
449
|
blockerState,
|
|
@@ -442,15 +451,12 @@ var RouterProvider = ({ children, routeList, context: initialContext = {}, isAni
|
|
|
442
451
|
setContext,
|
|
443
452
|
routeList,
|
|
444
453
|
isLoading,
|
|
445
|
-
shouldErrorElementShown: loaderError || beforeLoadError,
|
|
446
454
|
isAnimated
|
|
447
455
|
}), [
|
|
448
|
-
beforeLoadError,
|
|
449
456
|
blockerState,
|
|
450
457
|
context,
|
|
451
458
|
isLoading,
|
|
452
|
-
|
|
453
|
-
loaderError,
|
|
459
|
+
loaderState,
|
|
454
460
|
location,
|
|
455
461
|
prefetchLoader,
|
|
456
462
|
routeList,
|
|
@@ -462,15 +468,6 @@ var RouterProvider = ({ children, routeList, context: initialContext = {}, isAni
|
|
|
462
468
|
});
|
|
463
469
|
};
|
|
464
470
|
//#endregion
|
|
465
|
-
//#region components/Spinner.tsx
|
|
466
|
-
var Spinner = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "cr-spinner" });
|
|
467
|
-
//#endregion
|
|
468
|
-
//#region utils/renderElement.tsx
|
|
469
|
-
var renderElement = (Component) => {
|
|
470
|
-
if (!Component) return null;
|
|
471
|
-
return typeof Component === "function" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, {}) : Component;
|
|
472
|
-
};
|
|
473
|
-
//#endregion
|
|
474
471
|
//#region hooks/useServiceContext.ts
|
|
475
472
|
var useServiceState = (reactContext) => {
|
|
476
473
|
const context = useContext(reactContext);
|
|
@@ -493,12 +490,22 @@ var ViewProvider = ({ children, params }) => {
|
|
|
493
490
|
});
|
|
494
491
|
};
|
|
495
492
|
//#endregion
|
|
493
|
+
//#region components/Spinner.tsx
|
|
494
|
+
var Spinner = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "cr-spinner" });
|
|
495
|
+
//#endregion
|
|
496
|
+
//#region utils/renderElement.tsx
|
|
497
|
+
var renderElement = (Component) => {
|
|
498
|
+
if (!Component) return null;
|
|
499
|
+
return typeof Component === "function" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, {}) : Component;
|
|
500
|
+
};
|
|
501
|
+
//#endregion
|
|
496
502
|
//#region components/Router.tsx
|
|
497
503
|
var PAGE_NOT_FOUND = "error 404. Page not found";
|
|
498
504
|
var ALL_LOCATIONS = "*";
|
|
499
505
|
var Router = ({ spinner = true }) => {
|
|
500
|
-
const { location, isLoading
|
|
506
|
+
const { location, isLoading } = useNavigationState();
|
|
501
507
|
const { routeList, isAnimated } = usePropsData();
|
|
508
|
+
const { loaderState } = useRouterData();
|
|
502
509
|
const routeItem = useMemo(() => {
|
|
503
510
|
if (!location.pathname) return void 0;
|
|
504
511
|
return routeList.find((el) => el.path === ALL_LOCATIONS || comparePaths(el, location.pathname));
|
|
@@ -507,6 +514,7 @@ var Router = ({ spinner = true }) => {
|
|
|
507
514
|
routeItem,
|
|
508
515
|
pathname: window.location.pathname
|
|
509
516
|
}), [routeItem]);
|
|
517
|
+
const shouldErrorElementShown = useMemo(() => Boolean(loaderState[location.pathname]?.loaderError || loaderState[location.pathname]?.beforeLoadError), [loaderState, location.pathname]);
|
|
510
518
|
if (spinner && !routeItem && isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {});
|
|
511
519
|
if (!routeItem && isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {});
|
|
512
520
|
if (!routeItem) return null;
|
|
@@ -581,8 +589,9 @@ var useParams = () => {
|
|
|
581
589
|
//#endregion
|
|
582
590
|
//#region hooks/useLoaderState.ts
|
|
583
591
|
var useLoaderState = () => {
|
|
584
|
-
const {
|
|
585
|
-
|
|
592
|
+
const { pathname } = useLocation();
|
|
593
|
+
const { loaderState } = useRouterData();
|
|
594
|
+
return loaderState[pathname];
|
|
586
595
|
};
|
|
587
596
|
//#endregion
|
|
588
597
|
//#region hooks/useBlocker.ts
|
|
@@ -3,5 +3,5 @@ import { type ActionsContextValue, type DataContextValue, type NavigationContext
|
|
|
3
3
|
type ProviderProps = PropsContextValue & NavigationContextValue & ActionsContextValue & DataContextValue & {
|
|
4
4
|
children: ReactNode;
|
|
5
5
|
};
|
|
6
|
-
export declare const Provider: ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader,
|
|
6
|
+
export declare const Provider: ({ children, setContext, context, updateBlockedRoute, updateLocation, location, setLocation, prefetchLoader, loaderState, blockerState, routeList, isLoading, isAnimated, }: ProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
7
|
export {};
|
package/dist/types/global.d.ts
CHANGED