clear-react-router 1.7.8 → 1.8.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 +3 -2
- package/dist/cell.d.ts +2 -3
- package/dist/components/Link.d.ts +1 -1
- package/dist/components/Router.d.ts +1 -1
- package/dist/config/routerConfig.d.ts +1 -1
- package/dist/constants.d.ts +1 -1
- package/dist/{state/createState.d.ts → create.d.ts} +1 -2
- package/dist/hooks/useBlocker.d.ts +1 -1
- package/dist/hooks/useGetAction.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 -1
- 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 +299 -261
- package/dist/instance.d.ts +1 -0
- package/dist/runtime/invalidate.d.ts +4 -5
- 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} +42 -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/state/state.d.ts +0 -50
- package/dist/utils/getContext.d.ts +0 -4
package/README.md
CHANGED
|
@@ -456,10 +456,11 @@ await invalidate('/post/[id]/comment/[id]');
|
|
|
456
456
|
|
|
457
457
|
#### Including child routes
|
|
458
458
|
|
|
459
|
-
To revalidate
|
|
459
|
+
To revalidate routes together with their cached child routes, pass the `withChildren` option:
|
|
460
460
|
|
|
461
461
|
```tsx
|
|
462
|
-
await invalidate('/posts', { withChildren: true });
|
|
462
|
+
await invalidate('/posts', { withChildren: true });
|
|
463
|
+
await invalidate(['/posts', '/users'], { withChildren: true });
|
|
463
464
|
```
|
|
464
465
|
|
|
465
466
|
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
|
|
1
|
+
import { RouterProps } from '../types';
|
|
2
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;
|
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,4 +1,4 @@
|
|
|
1
1
|
export declare const useGetAction: (actionKey: string) => {
|
|
2
2
|
currentAction: (arg: FormData) => Promise<unknown> | Promise<void> | void | unknown;
|
|
3
|
-
invalidate:
|
|
3
|
+
invalidate: (pathList?: string | string[], options?: import("../types").InvalidateOptions) => Promise<void>;
|
|
4
4
|
};
|
|
@@ -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,2 @@
|
|
|
1
|
-
import type { Location } from '../types
|
|
1
|
+
import type { Location } from '../types';
|
|
2
2
|
export declare const useNavigate: () => (arg: 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';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Suspense, createContext, lazy, useCallback, useContext, useEffect, useM
|
|
|
2
2
|
//#region \0rolldown/runtime.js
|
|
3
3
|
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
4
4
|
//#endregion
|
|
5
|
-
//#region
|
|
5
|
+
//#region create.ts
|
|
6
6
|
var create = (initialState) => {
|
|
7
7
|
let state = initialState;
|
|
8
8
|
const subscribers = /* @__PURE__ */ new Set();
|
|
@@ -28,35 +28,25 @@ var create = (initialState) => {
|
|
|
28
28
|
var useGlobalState = ({ subscribe, getState, setState }) => {
|
|
29
29
|
return [useSyncExternalStore(subscribe, getState), setState];
|
|
30
30
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region utils/commitState.ts
|
|
33
|
+
var createCommitState = ({ isLoadingState, routeItemDataState, loaderFallbackState, currentLoaderState, prevPathnameRef, loaderStateRef }) => (nextLocation, routeItem) => {
|
|
34
|
+
routeItemDataState.setState({
|
|
35
|
+
routeItem,
|
|
36
|
+
location: nextLocation
|
|
37
|
+
});
|
|
38
|
+
currentLoaderState.setState(loaderStateRef.value);
|
|
39
|
+
isLoadingState.setState(false);
|
|
40
|
+
loaderFallbackState.setState(void 0);
|
|
41
|
+
prevPathnameRef.set(nextLocation.pathname);
|
|
42
|
+
const fullPath = nextLocation.search ? `${nextLocation.pathname}${nextLocation.search}` : nextLocation.pathname;
|
|
43
|
+
if (fullPath === window.location.pathname + window.location.search) return;
|
|
44
|
+
history.pushState(null, "", fullPath);
|
|
34
45
|
};
|
|
35
46
|
//#endregion
|
|
36
47
|
//#region constants.ts
|
|
37
48
|
var emptyLoaderState = {};
|
|
38
49
|
//#endregion
|
|
39
|
-
//#region state/state.ts
|
|
40
|
-
var isLoadingState = create(false);
|
|
41
|
-
var useIsLoading = () => useGlobalState(isLoadingState);
|
|
42
|
-
var useBlockedRoute = createState({
|
|
43
|
-
from: "",
|
|
44
|
-
to: ""
|
|
45
|
-
});
|
|
46
|
-
var loaderFallbackState = create(void 0);
|
|
47
|
-
var useLoaderFallback = () => useGlobalState(loaderFallbackState);
|
|
48
|
-
var routeItemDataState = create({
|
|
49
|
-
routeItem: void 0,
|
|
50
|
-
location: {}
|
|
51
|
-
});
|
|
52
|
-
var useRouteItemData = () => useGlobalState(routeItemDataState);
|
|
53
|
-
var currentLoaderState = create(emptyLoaderState);
|
|
54
|
-
var useCurrentLoaderState = () => useGlobalState(currentLoaderState);
|
|
55
|
-
var scrollMapState = create({});
|
|
56
|
-
var useScrollMap = () => useGlobalState(scrollMapState);
|
|
57
|
-
var contextState = create({});
|
|
58
|
-
var useContextState = () => useGlobalState(contextState);
|
|
59
|
-
//#endregion
|
|
60
50
|
//#region \0@oxc-project+runtime@0.133.0/helpers/esm/typeof.js
|
|
61
51
|
function _typeof(o) {
|
|
62
52
|
"@babel/helpers - typeof";
|
|
@@ -95,25 +85,39 @@ function _defineProperty(e, r, t) {
|
|
|
95
85
|
}) : e[r] = t, e;
|
|
96
86
|
}
|
|
97
87
|
//#endregion
|
|
98
|
-
//#region
|
|
99
|
-
var
|
|
100
|
-
constructor(
|
|
101
|
-
_defineProperty(this, "
|
|
102
|
-
this
|
|
88
|
+
//#region config/routerConfig.ts
|
|
89
|
+
var RouterConfig = class {
|
|
90
|
+
constructor() {
|
|
91
|
+
_defineProperty(this, "routes", []);
|
|
92
|
+
_defineProperty(this, "prefetch", "hover");
|
|
93
|
+
_defineProperty(this, "isAnimated", false);
|
|
94
|
+
_defineProperty(this, "showFallbackOnAnimation", false);
|
|
95
|
+
_defineProperty(this, "hoverPrefetchDelay", 150);
|
|
96
|
+
_defineProperty(this, "beforeLoad", void 0);
|
|
97
|
+
_defineProperty(this, "afterLoad", void 0);
|
|
103
98
|
}
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
configure(config) {
|
|
100
|
+
Object.assign(this, config);
|
|
106
101
|
}
|
|
107
|
-
|
|
108
|
-
|
|
102
|
+
};
|
|
103
|
+
var routerConfig = new RouterConfig();
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region utils/commitNavigation.ts
|
|
106
|
+
var createCommitNavigation = (navigationExecutor, prevPathnameRef) => (nextLocation, routeItem) => {
|
|
107
|
+
const { isAnimated } = routerConfig;
|
|
108
|
+
if (!isAnimated || !prevPathnameRef.value) {
|
|
109
|
+
navigationExecutor(nextLocation, routeItem);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
document.startViewTransition(() => navigationExecutor(nextLocation, routeItem));
|
|
114
|
+
} catch {
|
|
115
|
+
navigationExecutor(nextLocation, routeItem);
|
|
109
116
|
}
|
|
110
117
|
};
|
|
111
|
-
var loaderStateRef = new Cell(emptyLoaderState);
|
|
112
|
-
var prevPathnameRef = new Cell("");
|
|
113
|
-
var timestampMap = /* @__PURE__ */ new Map();
|
|
114
118
|
//#endregion
|
|
115
119
|
//#region utils/isCacheItemFresh.ts
|
|
116
|
-
var
|
|
120
|
+
var createIsCacheItemFresh = (timestampMap) => ({ routeItem, pathname }) => {
|
|
117
121
|
if (!routeItem) return true;
|
|
118
122
|
const currentCacheTimestamp = timestampMap.get(pathname);
|
|
119
123
|
if (!currentCacheTimestamp) return false;
|
|
@@ -210,25 +214,183 @@ var parseWindowLocation = (location) => ({
|
|
|
210
214
|
search: location.search
|
|
211
215
|
});
|
|
212
216
|
var comparePaths = (el, pathname) => {
|
|
217
|
+
if (!el.params?.length) return el.path.replaceAll("/", "") === pathname.replaceAll("/", "");
|
|
213
218
|
const splitElementPath = el.path.split("/").filter(Boolean);
|
|
214
219
|
const paramsLength = el.params ? Object.keys(el.params).length : 0;
|
|
215
220
|
const splitPathname = pathname.split("/").filter(Boolean);
|
|
216
221
|
return splitElementPath.every((item, index) => item === splitPathname[2 * index]) && splitPathname.length === splitElementPath.length + paramsLength;
|
|
217
222
|
};
|
|
223
|
+
var findRoute = (pathname, includeAll) => {
|
|
224
|
+
if (includeAll) return routerConfig.routes.find((el) => el.path === "/*" || comparePaths(el, pathname));
|
|
225
|
+
return routerConfig.routes.find((el) => comparePaths(el, pathname));
|
|
226
|
+
};
|
|
218
227
|
//#endregion
|
|
219
|
-
//#region
|
|
220
|
-
var
|
|
221
|
-
|
|
228
|
+
//#region runtime/navigate.ts
|
|
229
|
+
var navigationSeq = 0;
|
|
230
|
+
var createNavigate = (routerSta, revalidateCache) => {
|
|
231
|
+
const { loaderStateRef, scrollMapState, prevPathnameRef, loaderFallbackState, isLoadingState, contextState, timestampMap } = routerSta;
|
|
232
|
+
const commitNavigation = createCommitNavigation(createCommitState(routerSta), prevPathnameRef);
|
|
233
|
+
const isCacheItemFresh = createIsCacheItemFresh(timestampMap);
|
|
234
|
+
const getContext = () => ({
|
|
222
235
|
context: contextState.getState(),
|
|
223
236
|
setContext: contextState.setState
|
|
237
|
+
});
|
|
238
|
+
const routeResolve = (location) => {
|
|
239
|
+
loaderStateRef.set(emptyLoaderState);
|
|
240
|
+
const nextItem = findRoute(location.pathname, true);
|
|
241
|
+
return {
|
|
242
|
+
nextItem,
|
|
243
|
+
params: getParamsObject({
|
|
244
|
+
params: nextItem?.params,
|
|
245
|
+
pathname: location.pathname
|
|
246
|
+
})
|
|
247
|
+
};
|
|
224
248
|
};
|
|
249
|
+
const beforeLoad = async (routeItem, params) => {
|
|
250
|
+
const { beforeLoad } = routerConfig;
|
|
251
|
+
const runBeforeLoad = async (loaderFn) => {
|
|
252
|
+
const redirect = async (redirected) => await navigate(typeof redirected === "string" ? { pathname: redirected } : redirected);
|
|
253
|
+
try {
|
|
254
|
+
await loaderFn({
|
|
255
|
+
...getContext(),
|
|
256
|
+
redirect,
|
|
257
|
+
params
|
|
258
|
+
});
|
|
259
|
+
loaderStateRef.set((prev) => ({
|
|
260
|
+
...prev,
|
|
261
|
+
beforeLoadError: null
|
|
262
|
+
}));
|
|
263
|
+
} catch (error) {
|
|
264
|
+
loaderStateRef.set((prev) => ({
|
|
265
|
+
...prev,
|
|
266
|
+
beforeLoadError: error
|
|
267
|
+
}));
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
if (beforeLoad) await runBeforeLoad(beforeLoad);
|
|
271
|
+
if (routeItem?.beforeLoad) await runBeforeLoad(routeItem?.beforeLoad);
|
|
272
|
+
};
|
|
273
|
+
const prepareNavigation = (routeItem, location) => {
|
|
274
|
+
const { isAnimated, showFallbackOnAnimation: showFallback } = routerConfig;
|
|
275
|
+
scrollMapState.setState((prevState) => {
|
|
276
|
+
const scrollPosition = document.scrollingElement?.scrollTop ?? 0;
|
|
277
|
+
if (!scrollPosition || prevState[prevPathnameRef.value] === scrollPosition) return prevState;
|
|
278
|
+
return {
|
|
279
|
+
...prevState,
|
|
280
|
+
[prevPathnameRef.value]: scrollPosition
|
|
281
|
+
};
|
|
282
|
+
});
|
|
283
|
+
loaderFallbackState.setState(isCacheItemFresh({
|
|
284
|
+
routeItem,
|
|
285
|
+
pathname: location.pathname
|
|
286
|
+
}) || isAnimated && !showFallback ? void 0 : routeItem?.loaderFallback);
|
|
287
|
+
};
|
|
288
|
+
const loader = async (routeItem, location) => {
|
|
289
|
+
if (!routeItem?.loader) return;
|
|
290
|
+
isLoadingState.setState(true);
|
|
291
|
+
await revalidateCache({
|
|
292
|
+
routeItem,
|
|
293
|
+
pathname: location.pathname
|
|
294
|
+
});
|
|
295
|
+
};
|
|
296
|
+
const afterLoad = async (routeItem, params) => {
|
|
297
|
+
const { afterLoad } = routerConfig;
|
|
298
|
+
if (routeItem?.afterLoad) await routeItem.afterLoad({
|
|
299
|
+
...getContext(),
|
|
300
|
+
params
|
|
301
|
+
});
|
|
302
|
+
if (afterLoad) await afterLoad({
|
|
303
|
+
...getContext(),
|
|
304
|
+
params
|
|
305
|
+
});
|
|
306
|
+
};
|
|
307
|
+
const navigate = async (nextLocation) => {
|
|
308
|
+
navigationSeq = navigationSeq + 1;
|
|
309
|
+
const seq = navigationSeq;
|
|
310
|
+
const { nextItem, params } = routeResolve(nextLocation);
|
|
311
|
+
await beforeLoad(nextItem, params);
|
|
312
|
+
if (seq !== navigationSeq) return;
|
|
313
|
+
prepareNavigation(nextItem, nextLocation);
|
|
314
|
+
await loader(nextItem, nextLocation);
|
|
315
|
+
if (seq !== navigationSeq) return;
|
|
316
|
+
commitNavigation(nextLocation, nextItem);
|
|
317
|
+
await afterLoad(nextItem, params);
|
|
318
|
+
};
|
|
319
|
+
return navigate;
|
|
320
|
+
};
|
|
321
|
+
//#endregion
|
|
322
|
+
//#region runtime/invalidate.ts
|
|
323
|
+
var redirect = () => Promise.resolve();
|
|
324
|
+
var createInvalidate = ({ routeItemDataState, loaderStateRef, timestampMap, currentLoaderState, contextState }, revalidateCache) => {
|
|
325
|
+
const invalidatePath = async (routeItem, pathname) => {
|
|
326
|
+
const routePathname = routeItemDataState.getState().location.pathname;
|
|
327
|
+
timestampMap.delete(pathname);
|
|
328
|
+
const params = getParamsObject({
|
|
329
|
+
params: routeItem?.params,
|
|
330
|
+
pathname
|
|
331
|
+
});
|
|
332
|
+
try {
|
|
333
|
+
if (routeItem?.beforeLoad) {
|
|
334
|
+
const context = contextState.getState();
|
|
335
|
+
const setContext = contextState.setState;
|
|
336
|
+
await routeItem.beforeLoad({
|
|
337
|
+
context,
|
|
338
|
+
redirect,
|
|
339
|
+
params,
|
|
340
|
+
setContext
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
loaderStateRef.set((prev) => ({
|
|
344
|
+
...prev,
|
|
345
|
+
beforeLoadError: null
|
|
346
|
+
}));
|
|
347
|
+
} catch (error) {
|
|
348
|
+
loaderStateRef.set((prev) => ({
|
|
349
|
+
...prev,
|
|
350
|
+
beforeLoadError: error
|
|
351
|
+
}));
|
|
352
|
+
}
|
|
353
|
+
await revalidateCache({
|
|
354
|
+
routeItem,
|
|
355
|
+
pathname
|
|
356
|
+
});
|
|
357
|
+
if (pathname === routePathname) currentLoaderState.setState(loaderStateRef.value);
|
|
358
|
+
};
|
|
359
|
+
const invalidateItem = async (pathname, withChildren) => {
|
|
360
|
+
const routeItem = findRoute(pathname);
|
|
361
|
+
if (!routeItem) return;
|
|
362
|
+
const pathnameArray = [];
|
|
363
|
+
for (const [key] of timestampMap) if (comparePaths(routeItem, key)) pathnameArray.push(key);
|
|
364
|
+
await Promise.all(pathnameArray.map((pathname) => invalidatePath(routeItem, pathname)));
|
|
365
|
+
if (withChildren && routeItem.children?.length) {
|
|
366
|
+
const childPathList = routeItem.children.map((el) => el.path);
|
|
367
|
+
await Promise.all(childPathList.map((el) => invalidateItem(`${pathname}${el}`, true)));
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
async function invalidate(pathList, options) {
|
|
371
|
+
const routePathname = routeItemDataState.getState().location.pathname;
|
|
372
|
+
const pathnameList = Array.isArray(pathList) ? pathList : pathList ? [pathList] : [routePathname];
|
|
373
|
+
await Promise.all(pathnameList.map((pathname) => invalidateItem(pathname, options?.withChildren)));
|
|
374
|
+
}
|
|
375
|
+
return invalidate;
|
|
376
|
+
};
|
|
377
|
+
//#endregion
|
|
378
|
+
//#region runtime/prefetch.ts
|
|
379
|
+
var createPrefetch = (revalidateCache) => async (pathname) => {
|
|
380
|
+
const item = findRoute(pathname);
|
|
381
|
+
if (item) await revalidateCache({
|
|
382
|
+
routeItem: item,
|
|
383
|
+
pathname
|
|
384
|
+
});
|
|
225
385
|
};
|
|
226
386
|
//#endregion
|
|
227
387
|
//#region utils/revalidateCache.ts
|
|
228
388
|
var loaderMapRef = {};
|
|
229
389
|
var loadingPromises = /* @__PURE__ */ new Map();
|
|
230
|
-
var
|
|
390
|
+
var createRevalidateCache = (routerState) => ({ routeItem, pathname }) => {
|
|
231
391
|
if (!routeItem?.loader) return;
|
|
392
|
+
const isCacheItemFresh = createIsCacheItemFresh(routerState.timestampMap);
|
|
393
|
+
const { loaderStateRef, timestampMap, contextState } = routerState;
|
|
232
394
|
if (loadingPromises.has(pathname)) return loadingPromises.get(pathname);
|
|
233
395
|
if (isCacheItemFresh({
|
|
234
396
|
routeItem,
|
|
@@ -240,7 +402,8 @@ var revalidateCache = ({ routeItem, pathname }) => {
|
|
|
240
402
|
const promise = (async () => {
|
|
241
403
|
if (!routeItem?.loader) return;
|
|
242
404
|
try {
|
|
243
|
-
const
|
|
405
|
+
const context = contextState.getState();
|
|
406
|
+
const setContext = contextState.setState;
|
|
244
407
|
const params = getParamsObject({
|
|
245
408
|
params: routeItem.params,
|
|
246
409
|
pathname
|
|
@@ -271,153 +434,82 @@ var revalidateCache = ({ routeItem, pathname }) => {
|
|
|
271
434
|
return promise;
|
|
272
435
|
};
|
|
273
436
|
//#endregion
|
|
274
|
-
//#region
|
|
275
|
-
var
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
});
|
|
280
|
-
currentLoaderState.setState(loaderStateRef.value);
|
|
281
|
-
isLoadingState.setState(false);
|
|
282
|
-
loaderFallbackState.setState(void 0);
|
|
283
|
-
prevPathnameRef.set(nextLocation.pathname);
|
|
284
|
-
const fullPath = nextLocation.search ? `${nextLocation.pathname}${nextLocation.search}` : nextLocation.pathname;
|
|
285
|
-
if (fullPath === window.location.pathname + window.location.search) return;
|
|
286
|
-
history.pushState(null, "", fullPath);
|
|
287
|
-
};
|
|
288
|
-
//#endregion
|
|
289
|
-
//#region config/routerConfig.ts
|
|
290
|
-
var RouterConfig = class {
|
|
291
|
-
constructor() {
|
|
292
|
-
_defineProperty(this, "routes", []);
|
|
293
|
-
_defineProperty(this, "prefetch", "hover");
|
|
294
|
-
_defineProperty(this, "isAnimated", false);
|
|
295
|
-
_defineProperty(this, "showFallbackOnAnimation", false);
|
|
296
|
-
_defineProperty(this, "hoverPrefetchDelay", 150);
|
|
297
|
-
_defineProperty(this, "beforeLoad", void 0);
|
|
298
|
-
_defineProperty(this, "afterLoad", void 0);
|
|
299
|
-
}
|
|
300
|
-
configure(config) {
|
|
301
|
-
Object.assign(this, config);
|
|
437
|
+
//#region cell.ts
|
|
438
|
+
var Cell = class {
|
|
439
|
+
constructor(_value) {
|
|
440
|
+
_defineProperty(this, "_value", void 0);
|
|
441
|
+
this._value = _value;
|
|
302
442
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
//#endregion
|
|
306
|
-
//#region utils/commitNavigation.ts
|
|
307
|
-
var commitNavigation = (nextLocation, routeItem) => {
|
|
308
|
-
const { isAnimated } = routerConfig;
|
|
309
|
-
if (!isAnimated || !prevPathnameRef.value) {
|
|
310
|
-
commitState(nextLocation, routeItem);
|
|
311
|
-
return;
|
|
443
|
+
get value() {
|
|
444
|
+
return this._value;
|
|
312
445
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
} catch {
|
|
316
|
-
commitState(nextLocation, routeItem);
|
|
446
|
+
set(action) {
|
|
447
|
+
this._value = typeof action === "function" ? action(this._value) : action;
|
|
317
448
|
}
|
|
318
449
|
};
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
return routerConfig.routes.find((el) => el.path === "*" || comparePaths(el, pathname));
|
|
322
|
-
};
|
|
450
|
+
new Cell(emptyLoaderState);
|
|
451
|
+
new Cell("");
|
|
323
452
|
//#endregion
|
|
324
|
-
//#region
|
|
325
|
-
var
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
})
|
|
453
|
+
//#region utils/createRouterInstance.ts
|
|
454
|
+
var createRouterInstance = () => {
|
|
455
|
+
const routerState = {
|
|
456
|
+
isLoadingState: create(false),
|
|
457
|
+
loaderFallbackState: create(void 0),
|
|
458
|
+
routeItemDataState: create({
|
|
459
|
+
routeItem: void 0,
|
|
460
|
+
location: {}
|
|
461
|
+
}),
|
|
462
|
+
currentLoaderState: create(emptyLoaderState),
|
|
463
|
+
scrollMapState: create({}),
|
|
464
|
+
contextState: create({}),
|
|
465
|
+
blockedRouteState: create({
|
|
466
|
+
from: "",
|
|
467
|
+
to: ""
|
|
468
|
+
}),
|
|
469
|
+
loaderStateRef: new Cell(emptyLoaderState),
|
|
470
|
+
prevPathnameRef: new Cell(""),
|
|
471
|
+
timestampMap: /* @__PURE__ */ new Map()
|
|
335
472
|
};
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
473
|
+
const revalidateCache = createRevalidateCache(routerState);
|
|
474
|
+
return {
|
|
475
|
+
state: {
|
|
476
|
+
isLoadingState: routerState.isLoadingState,
|
|
477
|
+
loaderFallbackState: routerState.loaderFallbackState,
|
|
478
|
+
routeItemDataState: routerState.routeItemDataState,
|
|
479
|
+
currentLoaderState: routerState.currentLoaderState,
|
|
480
|
+
scrollMapState: routerState.scrollMapState,
|
|
481
|
+
contextState: routerState.contextState,
|
|
482
|
+
blockedRouteState: routerState.blockedRouteState,
|
|
483
|
+
prevPathnameRef: routerState.prevPathnameRef
|
|
484
|
+
},
|
|
485
|
+
runtime: {
|
|
486
|
+
navigate: createNavigate(routerState, revalidateCache),
|
|
487
|
+
invalidate: createInvalidate(routerState, revalidateCache),
|
|
488
|
+
prefetch: createPrefetch(revalidateCache)
|
|
489
|
+
},
|
|
490
|
+
hooks: {
|
|
491
|
+
useIsLoading: () => useGlobalState(routerState.isLoadingState),
|
|
492
|
+
useBlockedRoute: () => useGlobalState(routerState.blockedRouteState),
|
|
493
|
+
useLoaderFallback: () => useGlobalState(routerState.loaderFallbackState),
|
|
494
|
+
useRouteItemData: () => useGlobalState(routerState.routeItemDataState),
|
|
495
|
+
useCurrentLoaderState: () => useGlobalState(routerState.currentLoaderState),
|
|
496
|
+
useScrollMap: () => useGlobalState(routerState.scrollMapState),
|
|
497
|
+
useContextState: () => useGlobalState(routerState.contextState)
|
|
358
498
|
}
|
|
359
499
|
};
|
|
360
|
-
if (beforeLoad) await runBeforeLoad(beforeLoad);
|
|
361
|
-
if (routeItem?.beforeLoad) await runBeforeLoad(routeItem?.beforeLoad);
|
|
362
|
-
};
|
|
363
|
-
var prepareNavigation = (routeItem, location) => {
|
|
364
|
-
const { isAnimated, showFallbackOnAnimation: showFallback } = routerConfig;
|
|
365
|
-
scrollMapState.setState((prevState) => {
|
|
366
|
-
const scrollPosition = document.scrollingElement?.scrollTop ?? 0;
|
|
367
|
-
if (!scrollPosition || prevState[prevPathnameRef.value] === scrollPosition) return prevState;
|
|
368
|
-
return {
|
|
369
|
-
...prevState,
|
|
370
|
-
[prevPathnameRef.value]: scrollPosition
|
|
371
|
-
};
|
|
372
|
-
});
|
|
373
|
-
loaderFallbackState.setState(isCacheItemFresh({
|
|
374
|
-
routeItem,
|
|
375
|
-
pathname: location.pathname
|
|
376
|
-
}) || isAnimated && !showFallback ? void 0 : routeItem?.loaderFallback);
|
|
377
|
-
};
|
|
378
|
-
var loader = async (routeItem, location) => {
|
|
379
|
-
if (!routeItem?.loader) return;
|
|
380
|
-
isLoadingState.setState(true);
|
|
381
|
-
await revalidateCache({
|
|
382
|
-
routeItem,
|
|
383
|
-
pathname: location.pathname
|
|
384
|
-
});
|
|
385
|
-
};
|
|
386
|
-
var afterLoad = async (routeItem, params) => {
|
|
387
|
-
const { afterLoad } = routerConfig;
|
|
388
|
-
const { context, setContext } = getContext();
|
|
389
|
-
if (routeItem?.afterLoad) await routeItem.afterLoad({
|
|
390
|
-
context,
|
|
391
|
-
params,
|
|
392
|
-
setContext
|
|
393
|
-
});
|
|
394
|
-
if (afterLoad) await afterLoad({
|
|
395
|
-
context,
|
|
396
|
-
params,
|
|
397
|
-
setContext
|
|
398
|
-
});
|
|
399
|
-
};
|
|
400
|
-
var navigate = async (nextLocation) => {
|
|
401
|
-
navigationSeq = navigationSeq + 1;
|
|
402
|
-
const seq = navigationSeq;
|
|
403
|
-
const { nextItem, params } = routeResolve(nextLocation);
|
|
404
|
-
await beforeLoad(nextItem, params);
|
|
405
|
-
if (seq !== navigationSeq) return;
|
|
406
|
-
prepareNavigation(nextItem, nextLocation);
|
|
407
|
-
await loader(nextItem, nextLocation);
|
|
408
|
-
if (seq !== navigationSeq) return;
|
|
409
|
-
commitNavigation(nextLocation, nextItem);
|
|
410
|
-
await afterLoad(nextItem, params);
|
|
411
500
|
};
|
|
412
501
|
//#endregion
|
|
502
|
+
//#region instance.ts
|
|
503
|
+
var router = createRouterInstance();
|
|
504
|
+
//#endregion
|
|
413
505
|
//#region hooks/useNavigation.ts
|
|
414
506
|
var useNavigation = () => {
|
|
415
|
-
const
|
|
507
|
+
const { state: { prevPathnameRef, blockedRouteState }, runtime: { navigate } } = router;
|
|
416
508
|
useEffect(() => {
|
|
417
509
|
const handler = async (event) => {
|
|
418
510
|
const newLocation = parseWindowLocation(event.target.location);
|
|
419
|
-
if (prevPathnameRef.value ===
|
|
420
|
-
|
|
511
|
+
if (prevPathnameRef.value === blockedRouteState.getState().from) {
|
|
512
|
+
blockedRouteState.setState({
|
|
421
513
|
from: prevPathnameRef.value,
|
|
422
514
|
to: newLocation.pathname
|
|
423
515
|
});
|
|
@@ -426,12 +518,16 @@ var useNavigation = () => {
|
|
|
426
518
|
};
|
|
427
519
|
window.addEventListener("popstate", handler);
|
|
428
520
|
return () => window.removeEventListener("popstate", handler);
|
|
429
|
-
}, [
|
|
521
|
+
}, [
|
|
522
|
+
blockedRouteState,
|
|
523
|
+
navigate,
|
|
524
|
+
prevPathnameRef.value
|
|
525
|
+
]);
|
|
430
526
|
useEffect(() => {
|
|
431
527
|
const currentLocation = parseWindowLocation(window.location);
|
|
432
528
|
navigate(currentLocation);
|
|
433
529
|
prevPathnameRef.set(currentLocation.pathname);
|
|
434
|
-
}, []);
|
|
530
|
+
}, [navigate, prevPathnameRef]);
|
|
435
531
|
};
|
|
436
532
|
//#endregion
|
|
437
533
|
//#region hooks/useApplyCustomAnimation.ts
|
|
@@ -473,6 +569,7 @@ var useApplyCustomAnimation = (animationDuration) => {
|
|
|
473
569
|
//#endregion
|
|
474
570
|
//#region hooks/usePreserveScroll.ts
|
|
475
571
|
var usePreserveScroll = (preserveScroll) => {
|
|
572
|
+
const { useRouteItemData, useScrollMap } = router.hooks;
|
|
476
573
|
const [routeItemData] = useRouteItemData();
|
|
477
574
|
const [scrollMap] = useScrollMap();
|
|
478
575
|
const { pathname } = routeItemData.location;
|
|
@@ -501,7 +598,7 @@ var useSetRouterConfig = (routerProps) => {
|
|
|
501
598
|
//#endregion
|
|
502
599
|
//#region hooks/useSetInitialContext.ts
|
|
503
600
|
var useSetInitialContext = (initialContext) => {
|
|
504
|
-
const [, setContext] = useContextState();
|
|
601
|
+
const [, setContext] = router.hooks.useContextState();
|
|
505
602
|
useEffect(() => {
|
|
506
603
|
if (initialContext) setContext(initialContext);
|
|
507
604
|
}, [initialContext, setContext]);
|
|
@@ -519,6 +616,7 @@ var renderElement = (Component) => {
|
|
|
519
616
|
//#region components/Router.tsx
|
|
520
617
|
var EmptyBoundary = ({ children }) => children;
|
|
521
618
|
var Router = ({ routes, beforeLoad, afterLoad, animationDuration, isAnimated = false, spinner = true, preserveScroll = true, showFallbackOnAnimation = false, prefetch = "hover", hoverPrefetchDelay = 150, errorBoundary: ErrorBoundary = EmptyBoundary, context: initialContext, defaultLoaderFallback, defaultErrorElement }) => {
|
|
619
|
+
const { useIsLoading, useLoaderFallback, useRouteItemData, useCurrentLoaderState } = router.hooks;
|
|
522
620
|
const [isLoading] = useIsLoading();
|
|
523
621
|
const [currentLoaderFallback] = useLoaderFallback();
|
|
524
622
|
const [routeItemData] = useRouteItemData();
|
|
@@ -550,18 +648,9 @@ var Router = ({ routes, beforeLoad, afterLoad, animationDuration, isAnimated = f
|
|
|
550
648
|
});
|
|
551
649
|
};
|
|
552
650
|
//#endregion
|
|
553
|
-
//#region runtime/prefetch.ts
|
|
554
|
-
var prefetch = async (pathname) => {
|
|
555
|
-
const item = findRoute(pathname);
|
|
556
|
-
if (item) await revalidateCache({
|
|
557
|
-
routeItem: item,
|
|
558
|
-
pathname
|
|
559
|
-
});
|
|
560
|
-
};
|
|
561
|
-
//#endregion
|
|
562
651
|
//#region hooks/useLocation.ts
|
|
563
652
|
var useLocation = () => {
|
|
564
|
-
const [routeItemData] = useRouteItemData();
|
|
653
|
+
const [routeItemData] = router.hooks.useRouteItemData();
|
|
565
654
|
return routeItemData.location;
|
|
566
655
|
};
|
|
567
656
|
//#endregion
|
|
@@ -576,11 +665,10 @@ var useLatest = (value) => {
|
|
|
576
665
|
//#endregion
|
|
577
666
|
//#region hooks/useNavigate.ts
|
|
578
667
|
var useNavigate = () => {
|
|
579
|
-
const [blockedRoute, setBlockedRoute] = useBlockedRoute();
|
|
668
|
+
const [blockedRoute, setBlockedRoute] = router.hooks.useBlockedRoute();
|
|
580
669
|
const locationRef = useLatest(useLocation());
|
|
581
670
|
const blockedRouteRef = useLatest(blockedRoute);
|
|
582
671
|
return useCallback(async (arg) => {
|
|
583
|
-
if (!navigate) throw new Error("Router has not been initialized. Did you forget to render <Router />?");
|
|
584
672
|
if (arg !== -1 && blockedRouteRef.current.from) {
|
|
585
673
|
const to = typeof arg === "object" ? arg.pathname : arg;
|
|
586
674
|
setBlockedRoute((prevState) => ({
|
|
@@ -591,8 +679,8 @@ var useNavigate = () => {
|
|
|
591
679
|
}
|
|
592
680
|
if (arg === -1) return history.go(arg);
|
|
593
681
|
if (typeof arg === "string") {
|
|
594
|
-
if (arg !== locationRef.current.pathname) await navigate({ pathname: arg });
|
|
595
|
-
} else if (JSON.stringify(arg) !== JSON.stringify(locationRef.current)) await navigate(arg);
|
|
682
|
+
if (arg !== locationRef.current.pathname) await router.runtime.navigate({ pathname: arg });
|
|
683
|
+
} else if (JSON.stringify(arg) !== JSON.stringify(locationRef.current)) await router.runtime.navigate(arg);
|
|
596
684
|
}, [
|
|
597
685
|
blockedRouteRef,
|
|
598
686
|
locationRef,
|
|
@@ -603,45 +691,45 @@ var useNavigate = () => {
|
|
|
603
691
|
//#region components/Link.tsx
|
|
604
692
|
var Link = ({ children, to, prefetch: prefetchLink, hoverPrefetchDelay }) => {
|
|
605
693
|
const { prefetch: configPrefetch, hoverPrefetchDelay: configPrefetchDelay } = routerConfig;
|
|
606
|
-
const prefetch
|
|
694
|
+
const prefetch = prefetchLink || configPrefetch;
|
|
607
695
|
const prefetchDelay = hoverPrefetchDelay ?? configPrefetchDelay;
|
|
608
696
|
const navigate = useNavigate();
|
|
609
697
|
const timeout = useRef(0);
|
|
610
698
|
const ref = useRef(null);
|
|
611
699
|
const onMouseEnter = useCallback(() => {
|
|
612
|
-
if (prefetch
|
|
700
|
+
if (prefetch !== "hover" || !prefetchDelay) return;
|
|
613
701
|
if (timeout.current) clearTimeout(timeout.current);
|
|
614
|
-
timeout.current = window.setTimeout(() => prefetch(to), prefetchDelay);
|
|
702
|
+
timeout.current = window.setTimeout(() => router.runtime.prefetch(to), prefetchDelay);
|
|
615
703
|
}, [
|
|
616
|
-
prefetch
|
|
704
|
+
prefetch,
|
|
617
705
|
prefetchDelay,
|
|
618
706
|
to
|
|
619
707
|
]);
|
|
620
708
|
const onMouseLeave = useCallback(() => {
|
|
621
|
-
if (prefetch
|
|
709
|
+
if (prefetch !== "hover" || !prefetchDelay) return;
|
|
622
710
|
if (timeout.current) {
|
|
623
711
|
clearTimeout(timeout.current);
|
|
624
712
|
timeout.current = 0;
|
|
625
713
|
}
|
|
626
|
-
}, [prefetch
|
|
714
|
+
}, [prefetch, prefetchDelay]);
|
|
627
715
|
useEffect(() => {
|
|
628
|
-
if (prefetch
|
|
716
|
+
if (prefetch !== "render") return;
|
|
629
717
|
(async () => {
|
|
630
|
-
await prefetch(to);
|
|
718
|
+
await router.runtime.prefetch(to);
|
|
631
719
|
})();
|
|
632
|
-
}, [prefetch
|
|
720
|
+
}, [prefetch, to]);
|
|
633
721
|
useEffect(() => {
|
|
634
|
-
if (prefetch
|
|
722
|
+
if (prefetch !== "viewport") return;
|
|
635
723
|
const element = ref.current;
|
|
636
724
|
const observer = new IntersectionObserver(async () => {
|
|
637
|
-
await prefetch(to);
|
|
725
|
+
await router.runtime.prefetch(to);
|
|
638
726
|
observer.disconnect();
|
|
639
727
|
});
|
|
640
728
|
if (element) observer.observe(element);
|
|
641
729
|
return () => {
|
|
642
730
|
if (element) observer.disconnect();
|
|
643
731
|
};
|
|
644
|
-
}, [prefetch
|
|
732
|
+
}, [prefetch, to]);
|
|
645
733
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
646
734
|
ref,
|
|
647
735
|
style: { cursor: "pointer" },
|
|
@@ -661,64 +749,12 @@ var FormProvider = ({ children, isSubmitting }) => /* @__PURE__ */ (0, import_js
|
|
|
661
749
|
children
|
|
662
750
|
});
|
|
663
751
|
//#endregion
|
|
664
|
-
//#region runtime/invalidate.ts
|
|
665
|
-
var redirect = () => Promise.resolve();
|
|
666
|
-
var invalidatePath = async (routeItem, pathname) => {
|
|
667
|
-
const routePathname = routeItemDataState.getState().location.pathname;
|
|
668
|
-
timestampMap.delete(pathname);
|
|
669
|
-
const params = getParamsObject({
|
|
670
|
-
params: routeItem?.params,
|
|
671
|
-
pathname
|
|
672
|
-
});
|
|
673
|
-
try {
|
|
674
|
-
if (routeItem?.beforeLoad) {
|
|
675
|
-
const { context, setContext } = getContext();
|
|
676
|
-
await routeItem.beforeLoad({
|
|
677
|
-
context,
|
|
678
|
-
redirect,
|
|
679
|
-
params,
|
|
680
|
-
setContext
|
|
681
|
-
});
|
|
682
|
-
}
|
|
683
|
-
loaderStateRef.set((prev) => ({
|
|
684
|
-
...prev,
|
|
685
|
-
beforeLoadError: null
|
|
686
|
-
}));
|
|
687
|
-
} catch (error) {
|
|
688
|
-
loaderStateRef.set((prev) => ({
|
|
689
|
-
...prev,
|
|
690
|
-
beforeLoadError: error
|
|
691
|
-
}));
|
|
692
|
-
}
|
|
693
|
-
await revalidateCache({
|
|
694
|
-
routeItem,
|
|
695
|
-
pathname
|
|
696
|
-
});
|
|
697
|
-
if (pathname === routePathname) currentLoaderState.setState(loaderStateRef.value);
|
|
698
|
-
};
|
|
699
|
-
var invalidateItem = async (pathname, withChildren) => {
|
|
700
|
-
const routeItem = findRoute(pathname);
|
|
701
|
-
if (!routeItem) return;
|
|
702
|
-
const pathnameArray = [];
|
|
703
|
-
for (const [key] of timestampMap) if (comparePaths(routeItem, key)) pathnameArray.push(key);
|
|
704
|
-
await Promise.all(pathnameArray.map((pathname) => invalidatePath(routeItem, pathname)));
|
|
705
|
-
if (withChildren && routeItem.children?.length) {
|
|
706
|
-
const childPathList = routeItem.children.map((el) => el.path);
|
|
707
|
-
await Promise.all(childPathList.map((el) => invalidateItem(`${pathname}${el}`, withChildren)));
|
|
708
|
-
}
|
|
709
|
-
};
|
|
710
|
-
async function invalidate(pathList, options) {
|
|
711
|
-
const routePathname = routeItemDataState.getState().location.pathname;
|
|
712
|
-
const pathnameList = Array.isArray(pathList) ? pathList : pathList ? [pathList] : [routePathname];
|
|
713
|
-
await Promise.all(pathnameList.map((pathname) => invalidateItem(pathname, options?.withChildren)));
|
|
714
|
-
}
|
|
715
|
-
//#endregion
|
|
716
752
|
//#region hooks/useInvalidate.ts
|
|
717
|
-
var useInvalidate = () => invalidate;
|
|
753
|
+
var useInvalidate = () => router.runtime.invalidate;
|
|
718
754
|
//#endregion
|
|
719
755
|
//#region hooks/useParams.ts
|
|
720
756
|
var useParams = () => {
|
|
721
|
-
const [routeItemData] = useRouteItemData();
|
|
757
|
+
const [routeItemData] = router.hooks.useRouteItemData();
|
|
722
758
|
const { routeItem, location: { pathname } } = routeItemData;
|
|
723
759
|
return useMemo(() => routeItem ? getParamsObject({
|
|
724
760
|
params: routeItem?.params,
|
|
@@ -728,6 +764,7 @@ var useParams = () => {
|
|
|
728
764
|
//#endregion
|
|
729
765
|
//#region hooks/useGetAction.ts
|
|
730
766
|
var useGetAction = (actionKey) => {
|
|
767
|
+
const { useRouteItemData, useContextState } = router.hooks;
|
|
731
768
|
const invalidate = useInvalidate();
|
|
732
769
|
const [routeItemData] = useRouteItemData();
|
|
733
770
|
const [context, setContext] = useContextState();
|
|
@@ -778,12 +815,13 @@ var Form = ({ children, action, onSuccess, onError, autoReset = true }) => {
|
|
|
778
815
|
//#endregion
|
|
779
816
|
//#region hooks/useLoaderState.ts
|
|
780
817
|
var useLoaderState = () => {
|
|
781
|
-
const [loaderState] = useCurrentLoaderState();
|
|
818
|
+
const [loaderState] = router.hooks.useCurrentLoaderState();
|
|
782
819
|
return loaderState;
|
|
783
820
|
};
|
|
784
821
|
//#endregion
|
|
785
822
|
//#region hooks/useBlocker.ts
|
|
786
823
|
var useBlocker = (blockerFn) => {
|
|
824
|
+
const { hooks: { useBlockedRoute, useRouteItemData }, runtime: { navigate } } = router;
|
|
787
825
|
const [blockedRoute, setBlockedRoute] = useBlockedRoute();
|
|
788
826
|
const [routeItemData] = useRouteItemData();
|
|
789
827
|
const { location: { pathname } } = routeItemData;
|
|
@@ -803,7 +841,7 @@ var useBlocker = (blockerFn) => {
|
|
|
803
841
|
from: "",
|
|
804
842
|
to: ""
|
|
805
843
|
};
|
|
806
|
-
}), [setBlockedRoute]);
|
|
844
|
+
}), [navigate, setBlockedRoute]);
|
|
807
845
|
const blockerState = useMemo(() => {
|
|
808
846
|
if (blockedRoute.from && blockedRoute.to) return "blocked";
|
|
809
847
|
if (blockedRoute.from) return "charged";
|
|
@@ -848,7 +886,7 @@ var useAction = (action, options = {}) => {
|
|
|
848
886
|
//#endregion
|
|
849
887
|
//#region hooks/useRouterContext.ts
|
|
850
888
|
var useRouterContext = () => {
|
|
851
|
-
const [context, setContext] = useContextState();
|
|
889
|
+
const [context, setContext] = router.hooks.useContextState();
|
|
852
890
|
return {
|
|
853
891
|
context,
|
|
854
892
|
setContext
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const router: import("./types").RouterType;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
1
|
+
import { type InvalidateOptions, RevalidateCache, RouterState } from '../types';
|
|
2
|
+
export declare const createInvalidate: ({ routeItemDataState, loaderStateRef, timestampMap, currentLoaderState, contextState }: RouterState, revalidateCache: RevalidateCache) => {
|
|
3
|
+
(pathList?: string[]): Promise<void>;
|
|
4
|
+
(path?: string, options?: InvalidateOptions): Promise<void>;
|
|
3
5
|
};
|
|
4
|
-
export declare function invalidate(path?: string[]): Promise<void>;
|
|
5
|
-
export declare function invalidate(path?: string, options?: Options): Promise<void>;
|
|
6
|
-
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Location } from '../types
|
|
2
|
-
export declare const
|
|
1
|
+
import { Location, RevalidateCache, RouterState } from '../types';
|
|
2
|
+
export declare const createNavigate: (routerSta: RouterState, revalidateCache: RevalidateCache) => (nextLocation: Location) => Promise<void>;
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
import { RevalidateCache } from '../types';
|
|
2
|
+
export declare const createPrefetch: (revalidateCache: RevalidateCache) => (pathname: string) => Promise<void>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ComponentType, Dispatch, ReactElement, ReactNode, SetStateAction } from 'react';
|
|
2
|
+
import { Store, useGlobalState } from './create';
|
|
3
|
+
import { Cell } from './cell';
|
|
2
4
|
export type LazyComponent = () => Promise<{
|
|
3
5
|
default: ComponentType<unknown>;
|
|
4
6
|
}>;
|
|
@@ -9,11 +11,6 @@ export type BeforeLoad = (arg: {
|
|
|
9
11
|
params: Record<string, string>;
|
|
10
12
|
setContext: Dispatch<SetStateAction<Record<string, unknown>>>;
|
|
11
13
|
}) => Promise<unknown> | undefined | void;
|
|
12
|
-
export type AfterLoad = (arg: {
|
|
13
|
-
context: Record<string, unknown>;
|
|
14
|
-
params: Record<string, string>;
|
|
15
|
-
setContext: Dispatch<SetStateAction<Record<string, unknown>>>;
|
|
16
|
-
}) => Promise<void>;
|
|
17
14
|
export type ClientRouteItem = {
|
|
18
15
|
path: string;
|
|
19
16
|
element: RenderElement | LazyComponent;
|
|
@@ -63,7 +60,7 @@ export type LoaderState<T = unknown> = {
|
|
|
63
60
|
loaderError: Error | null;
|
|
64
61
|
beforeLoadError: Error | null;
|
|
65
62
|
};
|
|
66
|
-
export type
|
|
63
|
+
export type Adapter<T> = {
|
|
67
64
|
parse: (params: string[]) => T;
|
|
68
65
|
serialize?: (params: T) => string | string[];
|
|
69
66
|
};
|
|
@@ -89,3 +86,42 @@ export type RouterProps = {
|
|
|
89
86
|
afterLoad?: ClientRouteItem['afterLoad'];
|
|
90
87
|
context?: Record<string, unknown>;
|
|
91
88
|
};
|
|
89
|
+
export type RouterState = {
|
|
90
|
+
isLoadingState: Store<boolean>;
|
|
91
|
+
loaderFallbackState: Store<RouteItem['loaderFallback']>;
|
|
92
|
+
routeItemDataState: Store<RouteItemData>;
|
|
93
|
+
currentLoaderState: Store<LoaderState>;
|
|
94
|
+
scrollMapState: Store<Record<string, number>>;
|
|
95
|
+
contextState: Store<Record<string, unknown>>;
|
|
96
|
+
blockedRouteState: Store<{
|
|
97
|
+
from: string;
|
|
98
|
+
to: string;
|
|
99
|
+
}>;
|
|
100
|
+
loaderStateRef: Cell<LoaderState>;
|
|
101
|
+
prevPathnameRef: Cell<string>;
|
|
102
|
+
timestampMap: Map<string, number>;
|
|
103
|
+
};
|
|
104
|
+
export type RouterType = {
|
|
105
|
+
state: Omit<RouterState, 'loaderStateRef' | 'timestampMap'>;
|
|
106
|
+
runtime: {
|
|
107
|
+
navigate(arg: Location): Promise<void>;
|
|
108
|
+
invalidate(pathList?: string | string[], options?: InvalidateOptions): Promise<void>;
|
|
109
|
+
prefetch(pathname: string): Promise<void>;
|
|
110
|
+
};
|
|
111
|
+
hooks: {
|
|
112
|
+
useIsLoading: () => ReturnType<typeof useGlobalState<boolean>>;
|
|
113
|
+
useBlockedRoute: () => ReturnType<typeof useGlobalState<{
|
|
114
|
+
from: string;
|
|
115
|
+
to: string;
|
|
116
|
+
}>>;
|
|
117
|
+
useLoaderFallback: () => ReturnType<typeof useGlobalState<RenderElement | undefined>>;
|
|
118
|
+
useRouteItemData: () => ReturnType<typeof useGlobalState<RouteItemData>>;
|
|
119
|
+
useCurrentLoaderState: () => ReturnType<typeof useGlobalState<LoaderState<unknown>>>;
|
|
120
|
+
useScrollMap: () => ReturnType<typeof useGlobalState<Record<string, number>>>;
|
|
121
|
+
useContextState: () => ReturnType<typeof useGlobalState<Record<string, unknown>>>;
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
export type InvalidateOptions = {
|
|
125
|
+
withChildren?: boolean;
|
|
126
|
+
};
|
|
127
|
+
export type RevalidateCache = ({ routeItem, pathname }: RevalidateCacheArgs) => Promise<unknown> | undefined;
|
package/dist/utils/adapter.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Adapter } from '../types';
|
|
2
2
|
type ZodInterface<T> = {
|
|
3
3
|
safeParse(input: unknown): {
|
|
4
4
|
success: true;
|
|
@@ -46,6 +46,6 @@ export declare const adapter: {
|
|
|
46
46
|
parse: (params: string[]) => Date[];
|
|
47
47
|
serialize: (args: Date[]) => string[];
|
|
48
48
|
};
|
|
49
|
-
zodSchema: <T>(schema: ZodInterface<T>) =>
|
|
49
|
+
zodSchema: <T>(schema: ZodInterface<T>) => Adapter<T>;
|
|
50
50
|
};
|
|
51
51
|
export {};
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Cell } from '../cell';
|
|
2
|
+
import { Location, RouteItem } from '../types';
|
|
3
|
+
export declare const createCommitNavigation: (navigationExecutor: (arg: Location, routeItem: RouteItem | undefined) => void, prevPathnameRef: Cell<string>) => (nextLocation: Location, routeItem: RouteItem | undefined) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Location, RouteItem } from '../types
|
|
2
|
-
export declare const
|
|
1
|
+
import { Location, RouteItem, RouterState } from '../types';
|
|
2
|
+
export declare const createCommitState: ({ isLoadingState, routeItemDataState, loaderFallbackState, currentLoaderState, prevPathnameRef, loaderStateRef, }: RouterState) => (nextLocation: Location, routeItem: RouteItem | undefined) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const ALL_LOCATIONS = "
|
|
1
|
+
export declare const ALL_LOCATIONS = "/*";
|
|
2
2
|
export declare const findRoute: (pathname: string, includeAll?: boolean) => import("..").RouteItem | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RouteItem } from '../types
|
|
2
|
-
export declare const
|
|
1
|
+
import type { RouteItem } from '../types';
|
|
2
|
+
export declare const createIsCacheItemFresh: (timestampMap: Map<string, number>) => ({ routeItem, pathname }: {
|
|
3
3
|
routeItem?: RouteItem;
|
|
4
4
|
pathname: string;
|
|
5
5
|
}) => boolean;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { RenderElement } from '../types
|
|
1
|
+
import { RenderElement } from '../types';
|
|
2
2
|
export declare const renderElement: (Component?: RenderElement) => import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
declare const
|
|
3
|
-
export { revalidateCache };
|
|
1
|
+
import { RevalidateCacheArgs, RouterState } from '../types';
|
|
2
|
+
export declare const createRevalidateCache: (routerState: RouterState) => ({ routeItem, pathname }: RevalidateCacheArgs) => any;
|
package/dist/utils/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ClientRouteItem, Location, RouteItem } from '../types';
|
|
2
2
|
export declare const createRouter: (clientList: ClientRouteItem[]) => RouteItem[];
|
|
3
3
|
export declare const getParamsObject: ({ params, pathname }: {
|
|
4
4
|
params?: RouteItem["params"];
|
package/package.json
CHANGED
package/dist/state/state.d.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { LoaderState, RouteItemData } from '../types/global';
|
|
2
|
-
export declare const isLoadingState: {
|
|
3
|
-
subscribe: (listener: (state: boolean, prevState: boolean) => void) => () => void;
|
|
4
|
-
getState: () => boolean;
|
|
5
|
-
setState: (action: boolean | ((prevState: boolean) => boolean)) => void;
|
|
6
|
-
};
|
|
7
|
-
export declare const useIsLoading: () => readonly [boolean, (action: boolean | ((prevState: boolean) => boolean)) => void];
|
|
8
|
-
export declare const useBlockedRoute: () => readonly [{
|
|
9
|
-
from: string;
|
|
10
|
-
to: string;
|
|
11
|
-
}, (action: {
|
|
12
|
-
from: string;
|
|
13
|
-
to: string;
|
|
14
|
-
} | ((prevState: {
|
|
15
|
-
from: string;
|
|
16
|
-
to: string;
|
|
17
|
-
}) => {
|
|
18
|
-
from: string;
|
|
19
|
-
to: string;
|
|
20
|
-
})) => void];
|
|
21
|
-
export declare const loaderFallbackState: {
|
|
22
|
-
subscribe: (listener: (state: import("../types/global").RenderElement | undefined, prevState: import("../types/global").RenderElement | undefined) => void) => () => void;
|
|
23
|
-
getState: () => import("../types/global").RenderElement | undefined;
|
|
24
|
-
setState: (action: import("../types/global").RenderElement | ((prevState: import("../types/global").RenderElement | undefined) => import("../types/global").RenderElement | undefined) | undefined) => void;
|
|
25
|
-
};
|
|
26
|
-
export declare const useLoaderFallback: () => readonly [import("../types/global").RenderElement | undefined, (action: import("../types/global").RenderElement | ((prevState: import("../types/global").RenderElement | undefined) => import("../types/global").RenderElement | undefined) | undefined) => void];
|
|
27
|
-
export declare const routeItemDataState: {
|
|
28
|
-
subscribe: (listener: (state: RouteItemData, prevState: RouteItemData) => void) => () => void;
|
|
29
|
-
getState: () => RouteItemData;
|
|
30
|
-
setState: (action: RouteItemData | ((prevState: RouteItemData) => RouteItemData)) => void;
|
|
31
|
-
};
|
|
32
|
-
export declare const useRouteItemData: () => readonly [RouteItemData, (action: RouteItemData | ((prevState: RouteItemData) => RouteItemData)) => void];
|
|
33
|
-
export declare const currentLoaderState: {
|
|
34
|
-
subscribe: (listener: (state: LoaderState, prevState: LoaderState) => void) => () => void;
|
|
35
|
-
getState: () => LoaderState;
|
|
36
|
-
setState: (action: LoaderState | ((prevState: LoaderState) => LoaderState)) => void;
|
|
37
|
-
};
|
|
38
|
-
export declare const useCurrentLoaderState: () => readonly [LoaderState, (action: LoaderState | ((prevState: LoaderState) => LoaderState)) => void];
|
|
39
|
-
export declare const scrollMapState: {
|
|
40
|
-
subscribe: (listener: (state: Record<string, number>, prevState: Record<string, number>) => void) => () => void;
|
|
41
|
-
getState: () => Record<string, number>;
|
|
42
|
-
setState: (action: Record<string, number> | ((prevState: Record<string, number>) => Record<string, number>)) => void;
|
|
43
|
-
};
|
|
44
|
-
export declare const useScrollMap: () => readonly [Record<string, number>, (action: Record<string, number> | ((prevState: Record<string, number>) => Record<string, number>)) => void];
|
|
45
|
-
export declare const contextState: {
|
|
46
|
-
subscribe: (listener: (state: Record<string, unknown>, prevState: Record<string, unknown>) => void) => () => void;
|
|
47
|
-
getState: () => Record<string, unknown>;
|
|
48
|
-
setState: (action: Record<string, unknown> | ((prevState: Record<string, unknown>) => Record<string, unknown>)) => void;
|
|
49
|
-
};
|
|
50
|
-
export declare const useContextState: () => readonly [Record<string, unknown>, (action: Record<string, unknown> | ((prevState: Record<string, unknown>) => Record<string, unknown>)) => void];
|