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/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,40 @@ 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);
|
|
98
|
+
_defineProperty(this, "defaultRetry", void 0);
|
|
103
99
|
}
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
configure(config) {
|
|
101
|
+
Object.assign(this, config);
|
|
106
102
|
}
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
};
|
|
104
|
+
var routerConfig = new RouterConfig();
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region utils/commitNavigation.ts
|
|
107
|
+
var createCommitNavigation = (navigationExecutor, prevPathnameRef) => (nextLocation, routeItem) => {
|
|
108
|
+
const { isAnimated } = routerConfig;
|
|
109
|
+
if (!isAnimated || !prevPathnameRef.value) {
|
|
110
|
+
navigationExecutor(nextLocation, routeItem);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
document.startViewTransition(() => navigationExecutor(nextLocation, routeItem));
|
|
115
|
+
} catch {
|
|
116
|
+
navigationExecutor(nextLocation, routeItem);
|
|
109
117
|
}
|
|
110
118
|
};
|
|
111
|
-
var loaderStateRef = new Cell(emptyLoaderState);
|
|
112
|
-
var prevPathnameRef = new Cell("");
|
|
113
|
-
var timestampMap = /* @__PURE__ */ new Map();
|
|
114
119
|
//#endregion
|
|
115
120
|
//#region utils/isCacheItemFresh.ts
|
|
116
|
-
var
|
|
121
|
+
var createIsCacheItemFresh = (timestampMap) => ({ routeItem, pathname }) => {
|
|
117
122
|
if (!routeItem) return true;
|
|
118
123
|
const currentCacheTimestamp = timestampMap.get(pathname);
|
|
119
124
|
if (!currentCacheTimestamp) return false;
|
|
@@ -216,204 +221,397 @@ var comparePaths = (el, pathname) => {
|
|
|
216
221
|
const splitPathname = pathname.split("/").filter(Boolean);
|
|
217
222
|
return splitElementPath.every((item, index) => item === splitPathname[2 * index]) && splitPathname.length === splitElementPath.length + paramsLength;
|
|
218
223
|
};
|
|
224
|
+
var findRoute = (pathname, includeAll) => {
|
|
225
|
+
if (includeAll) return routerConfig.routes.find((el) => el.path === "/*" || comparePaths(el, pathname));
|
|
226
|
+
return routerConfig.routes.find((el) => comparePaths(el, pathname));
|
|
227
|
+
};
|
|
219
228
|
//#endregion
|
|
220
|
-
//#region
|
|
221
|
-
var
|
|
222
|
-
|
|
229
|
+
//#region runtime/navigate.ts
|
|
230
|
+
var navigationSeq = 0;
|
|
231
|
+
var createNavigate = (routerState, revalidateCache) => {
|
|
232
|
+
const { loaderStateRef, scrollMapState, prevPathnameRef, loaderFallbackState, isLoadingState, contextState, timestampMap } = routerState;
|
|
233
|
+
const commitNavigation = createCommitNavigation(createCommitState(routerState), prevPathnameRef);
|
|
234
|
+
const isCacheItemFresh = createIsCacheItemFresh(timestampMap);
|
|
235
|
+
const getContext = () => ({
|
|
223
236
|
context: contextState.getState(),
|
|
224
237
|
setContext: contextState.setState
|
|
238
|
+
});
|
|
239
|
+
const routeResolve = (location) => {
|
|
240
|
+
loaderStateRef.set(emptyLoaderState);
|
|
241
|
+
const nextItem = findRoute(location.pathname, true);
|
|
242
|
+
return {
|
|
243
|
+
nextItem,
|
|
244
|
+
params: getParamsObject({
|
|
245
|
+
params: nextItem?.params,
|
|
246
|
+
pathname: location.pathname
|
|
247
|
+
})
|
|
248
|
+
};
|
|
225
249
|
};
|
|
250
|
+
const beforeLoad = async (routeItem, params) => {
|
|
251
|
+
const { beforeLoad } = routerConfig;
|
|
252
|
+
const runBeforeLoad = async (loaderFn) => {
|
|
253
|
+
const redirect = async (redirected) => await navigate(typeof redirected === "string" ? { pathname: redirected } : redirected);
|
|
254
|
+
try {
|
|
255
|
+
await loaderFn({
|
|
256
|
+
...getContext(),
|
|
257
|
+
redirect,
|
|
258
|
+
params
|
|
259
|
+
});
|
|
260
|
+
loaderStateRef.set((prev) => ({
|
|
261
|
+
...prev,
|
|
262
|
+
beforeLoadError: null
|
|
263
|
+
}));
|
|
264
|
+
} catch (error) {
|
|
265
|
+
loaderStateRef.set((prev) => ({
|
|
266
|
+
...prev,
|
|
267
|
+
beforeLoadError: error
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
if (beforeLoad) await runBeforeLoad(beforeLoad);
|
|
272
|
+
if (routeItem?.beforeLoad) await runBeforeLoad(routeItem?.beforeLoad);
|
|
273
|
+
};
|
|
274
|
+
const prepareNavigation = (routeItem, location) => {
|
|
275
|
+
const { isAnimated, showFallbackOnAnimation: showFallback } = routerConfig;
|
|
276
|
+
scrollMapState.setState((prevState) => {
|
|
277
|
+
const scrollPosition = document.scrollingElement?.scrollTop ?? 0;
|
|
278
|
+
if (!scrollPosition || prevState[prevPathnameRef.value] === scrollPosition) return prevState;
|
|
279
|
+
return {
|
|
280
|
+
...prevState,
|
|
281
|
+
[prevPathnameRef.value]: scrollPosition
|
|
282
|
+
};
|
|
283
|
+
});
|
|
284
|
+
loaderFallbackState.setState(isCacheItemFresh({
|
|
285
|
+
routeItem,
|
|
286
|
+
pathname: location.pathname
|
|
287
|
+
}) || isAnimated && !showFallback ? void 0 : routeItem?.loaderFallback);
|
|
288
|
+
};
|
|
289
|
+
const loader = async (routeItem, location) => {
|
|
290
|
+
if (!routeItem?.loader) return;
|
|
291
|
+
isLoadingState.setState(true);
|
|
292
|
+
await revalidateCache({
|
|
293
|
+
routeItem,
|
|
294
|
+
pathname: location.pathname
|
|
295
|
+
});
|
|
296
|
+
};
|
|
297
|
+
const afterLoad = async (routeItem, params) => {
|
|
298
|
+
const { afterLoad } = routerConfig;
|
|
299
|
+
if (routeItem?.afterLoad) await routeItem.afterLoad({
|
|
300
|
+
...getContext(),
|
|
301
|
+
params
|
|
302
|
+
});
|
|
303
|
+
if (afterLoad) await afterLoad({
|
|
304
|
+
...getContext(),
|
|
305
|
+
params
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
const navigate = async (nextLocation) => {
|
|
309
|
+
navigationSeq = navigationSeq + 1;
|
|
310
|
+
const seq = navigationSeq;
|
|
311
|
+
const { nextItem, params } = routeResolve(nextLocation);
|
|
312
|
+
await beforeLoad(nextItem, params);
|
|
313
|
+
if (seq !== navigationSeq) return;
|
|
314
|
+
prepareNavigation(nextItem, nextLocation);
|
|
315
|
+
await loader(nextItem, nextLocation);
|
|
316
|
+
if (seq !== navigationSeq) return;
|
|
317
|
+
commitNavigation(nextLocation, nextItem);
|
|
318
|
+
await afterLoad(nextItem, params);
|
|
319
|
+
};
|
|
320
|
+
return navigate;
|
|
226
321
|
};
|
|
227
322
|
//#endregion
|
|
228
|
-
//#region
|
|
229
|
-
var
|
|
230
|
-
var
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
loaderStateRef.set(loaderMapRef[pathname]);
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
const promise = (async () => {
|
|
242
|
-
if (!routeItem?.loader) return;
|
|
323
|
+
//#region runtime/invalidate.ts
|
|
324
|
+
var redirect = () => Promise.resolve();
|
|
325
|
+
var createInvalidate = ({ routeItemDataState, loaderStateRef, timestampMap, currentLoaderState, contextState }, revalidateCache) => {
|
|
326
|
+
const invalidatePath = async (routeItem, pathname) => {
|
|
327
|
+
const routePathname = routeItemDataState.getState().location.pathname;
|
|
328
|
+
timestampMap.delete(pathname);
|
|
329
|
+
const params = getParamsObject({
|
|
330
|
+
params: routeItem?.params,
|
|
331
|
+
pathname
|
|
332
|
+
});
|
|
243
333
|
try {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
timestampMap.set(pathname, Date.now());
|
|
334
|
+
if (routeItem?.beforeLoad) {
|
|
335
|
+
const context = contextState.getState();
|
|
336
|
+
const setContext = contextState.setState;
|
|
337
|
+
await routeItem.beforeLoad({
|
|
338
|
+
context,
|
|
339
|
+
redirect,
|
|
340
|
+
params,
|
|
341
|
+
setContext
|
|
342
|
+
});
|
|
343
|
+
}
|
|
255
344
|
loaderStateRef.set((prev) => ({
|
|
256
345
|
...prev,
|
|
257
|
-
|
|
258
|
-
loaderError: null
|
|
346
|
+
beforeLoadError: null
|
|
259
347
|
}));
|
|
260
|
-
loaderMapRef[pathname] = loaderStateRef.value;
|
|
261
348
|
} catch (error) {
|
|
262
349
|
loaderStateRef.set((prev) => ({
|
|
263
350
|
...prev,
|
|
264
|
-
|
|
265
|
-
loaderError: error
|
|
351
|
+
beforeLoadError: error
|
|
266
352
|
}));
|
|
267
|
-
} finally {
|
|
268
|
-
loadingPromises.delete(pathname);
|
|
269
353
|
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
354
|
+
await revalidateCache({
|
|
355
|
+
routeItem,
|
|
356
|
+
pathname
|
|
357
|
+
});
|
|
358
|
+
if (pathname === routePathname) currentLoaderState.setState(loaderStateRef.value);
|
|
359
|
+
};
|
|
360
|
+
const invalidateItem = async (pathname, withChildren) => {
|
|
361
|
+
const routeItem = findRoute(pathname);
|
|
362
|
+
if (!routeItem) return;
|
|
363
|
+
const pathnameArray = [];
|
|
364
|
+
for (const [key] of timestampMap) if (comparePaths(routeItem, key)) pathnameArray.push(key);
|
|
365
|
+
await Promise.all(pathnameArray.map((pathname) => invalidatePath(routeItem, pathname)));
|
|
366
|
+
if (withChildren && routeItem.children?.length) {
|
|
367
|
+
const childPathList = routeItem.children.map((el) => el.path);
|
|
368
|
+
await Promise.all(childPathList.map((el) => invalidateItem(`${pathname}${el}`, true)));
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
return async (pathList, options) => {
|
|
372
|
+
const routePathname = routeItemDataState.getState().location.pathname;
|
|
373
|
+
const pathnameList = Array.isArray(pathList) ? pathList : pathList ? [pathList] : [routePathname];
|
|
374
|
+
await Promise.all(pathnameList.map((pathname) => invalidateItem(pathname, options?.withChildren)));
|
|
375
|
+
};
|
|
273
376
|
};
|
|
274
377
|
//#endregion
|
|
275
|
-
//#region
|
|
276
|
-
var
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
|
280
384
|
});
|
|
281
|
-
currentLoaderState.setState(loaderStateRef.value);
|
|
282
|
-
isLoadingState.setState(false);
|
|
283
|
-
loaderFallbackState.setState(void 0);
|
|
284
|
-
prevPathnameRef.set(nextLocation.pathname);
|
|
285
|
-
const fullPath = nextLocation.search ? `${nextLocation.pathname}${nextLocation.search}` : nextLocation.pathname;
|
|
286
|
-
if (fullPath === window.location.pathname + window.location.search) return;
|
|
287
|
-
history.pushState(null, "", fullPath);
|
|
288
385
|
};
|
|
289
386
|
//#endregion
|
|
290
|
-
//#region
|
|
291
|
-
var
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
387
|
+
//#region utils/revalidateCache.ts
|
|
388
|
+
var loaderMapRef = {};
|
|
389
|
+
var loadingPromises = /* @__PURE__ */ new Map();
|
|
390
|
+
var isObjectRetry = (arg) => typeof arg === "object";
|
|
391
|
+
var createRetry = (arg) => {
|
|
392
|
+
if (arg === void 0) return null;
|
|
393
|
+
return {
|
|
394
|
+
count: isObjectRetry(arg) ? arg.count : arg,
|
|
395
|
+
delay: isObjectRetry(arg) ? arg.delay : 0
|
|
396
|
+
};
|
|
397
|
+
};
|
|
398
|
+
var getRetry = (routeItem) => {
|
|
399
|
+
const routeRetry = createRetry(routeItem?.retry);
|
|
400
|
+
const globalRetry = createRetry(routerConfig.defaultRetry);
|
|
401
|
+
if (!routeRetry && !globalRetry) return null;
|
|
402
|
+
return {
|
|
403
|
+
count: routeRetry ? routeRetry.count : globalRetry?.count || 0,
|
|
404
|
+
delay: routeRetry ? routeRetry.delay : globalRetry?.delay || 0
|
|
405
|
+
};
|
|
406
|
+
};
|
|
407
|
+
var sleep = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
408
|
+
var createRevalidateCache = (routerState) => {
|
|
409
|
+
const revalidateCache = async ({ routeItem, pathname }, retried = 0) => {
|
|
410
|
+
if (!routeItem?.loader) return;
|
|
411
|
+
const isCacheItemFresh = createIsCacheItemFresh(routerState.timestampMap);
|
|
412
|
+
const { loaderStateRef, timestampMap, contextState } = routerState;
|
|
413
|
+
if (loadingPromises.has(pathname)) return loadingPromises.get(pathname);
|
|
414
|
+
if (isCacheItemFresh({
|
|
415
|
+
routeItem,
|
|
416
|
+
pathname
|
|
417
|
+
})) {
|
|
418
|
+
loaderStateRef.set(loaderMapRef[pathname]);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const promise = (async () => {
|
|
422
|
+
if (!routeItem?.loader) return;
|
|
423
|
+
try {
|
|
424
|
+
const context = contextState.getState();
|
|
425
|
+
const setContext = contextState.setState;
|
|
426
|
+
const params = getParamsObject({
|
|
427
|
+
params: routeItem.params,
|
|
428
|
+
pathname
|
|
429
|
+
});
|
|
430
|
+
const result = await routeItem?.loader({
|
|
431
|
+
params,
|
|
432
|
+
context,
|
|
433
|
+
setContext
|
|
434
|
+
});
|
|
435
|
+
timestampMap.set(pathname, Date.now());
|
|
436
|
+
loaderStateRef.set((prev) => ({
|
|
437
|
+
...prev,
|
|
438
|
+
data: result,
|
|
439
|
+
loaderError: null
|
|
440
|
+
}));
|
|
441
|
+
loaderMapRef[pathname] = loaderStateRef.value;
|
|
442
|
+
} catch (error) {
|
|
443
|
+
const retry = getRetry(routeItem);
|
|
444
|
+
if (retry && retry.count > retried) {
|
|
445
|
+
loadingPromises.delete(pathname);
|
|
446
|
+
if (retry.delay) await sleep(retry.delay);
|
|
447
|
+
await revalidateCache({
|
|
448
|
+
routeItem,
|
|
449
|
+
pathname
|
|
450
|
+
}, retried + 1);
|
|
451
|
+
} else loaderStateRef.set((prev) => ({
|
|
452
|
+
...prev,
|
|
453
|
+
data: null,
|
|
454
|
+
loaderError: error
|
|
455
|
+
}));
|
|
456
|
+
} finally {
|
|
457
|
+
loadingPromises.delete(pathname);
|
|
458
|
+
}
|
|
459
|
+
})();
|
|
460
|
+
loadingPromises.set(pathname, promise);
|
|
461
|
+
return promise;
|
|
462
|
+
};
|
|
463
|
+
return revalidateCache;
|
|
304
464
|
};
|
|
305
|
-
var routerConfig = new RouterConfig();
|
|
306
465
|
//#endregion
|
|
307
|
-
//#region
|
|
308
|
-
var
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return;
|
|
466
|
+
//#region cell.ts
|
|
467
|
+
var Cell = class {
|
|
468
|
+
constructor(_value) {
|
|
469
|
+
_defineProperty(this, "_value", void 0);
|
|
470
|
+
this._value = _value;
|
|
313
471
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
472
|
+
get value() {
|
|
473
|
+
return this._value;
|
|
474
|
+
}
|
|
475
|
+
set(action) {
|
|
476
|
+
this._value = typeof action === "function" ? action(this._value) : action;
|
|
318
477
|
}
|
|
319
478
|
};
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
return routerConfig.routes.find((el) => el.path === "*" || comparePaths(el, pathname));
|
|
323
|
-
};
|
|
479
|
+
new Cell(emptyLoaderState);
|
|
480
|
+
new Cell("");
|
|
324
481
|
//#endregion
|
|
325
|
-
//#region
|
|
326
|
-
var
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
482
|
+
//#region utils/createRouterInstance.ts
|
|
483
|
+
var createRouterInstance = () => {
|
|
484
|
+
const routerState = {
|
|
485
|
+
isLoadingState: create(false),
|
|
486
|
+
loaderFallbackState: create(void 0),
|
|
487
|
+
routeItemDataState: create({
|
|
488
|
+
routeItem: void 0,
|
|
489
|
+
location: {}
|
|
490
|
+
}),
|
|
491
|
+
currentLoaderState: create(emptyLoaderState),
|
|
492
|
+
scrollMapState: create({}),
|
|
493
|
+
contextState: create({}),
|
|
494
|
+
blockedRouteState: create({
|
|
495
|
+
from: "",
|
|
496
|
+
to: ""
|
|
497
|
+
}),
|
|
498
|
+
loaderStateRef: new Cell(emptyLoaderState),
|
|
499
|
+
prevPathnameRef: new Cell(""),
|
|
500
|
+
timestampMap: /* @__PURE__ */ new Map()
|
|
501
|
+
};
|
|
502
|
+
const revalidateCache = createRevalidateCache(routerState);
|
|
503
|
+
const navigate = createNavigate(routerState, revalidateCache);
|
|
504
|
+
const invalidate = createInvalidate(routerState, revalidateCache);
|
|
505
|
+
const prefetch = createPrefetch(revalidateCache);
|
|
506
|
+
const useGetAction = (actionKey) => {
|
|
507
|
+
const { routeItem, location } = routerState.routeItemDataState.getState();
|
|
508
|
+
const context = routerState.contextState.getState();
|
|
509
|
+
const setContext = routerState.contextState.setState;
|
|
510
|
+
const params = getParamsObject({
|
|
511
|
+
params: routeItem?.params,
|
|
334
512
|
pathname: location.pathname
|
|
335
|
-
})
|
|
513
|
+
});
|
|
514
|
+
if (!routeItem) throw new Error("Route not found");
|
|
515
|
+
if (!routeItem.actions) throw new Error("Route action creator not found");
|
|
516
|
+
const action = routeItem.actions({
|
|
517
|
+
context,
|
|
518
|
+
setContext,
|
|
519
|
+
params,
|
|
520
|
+
invalidate
|
|
521
|
+
})[actionKey];
|
|
522
|
+
if (!action) throw new Error(`Action "${actionKey}" not found`);
|
|
523
|
+
return {
|
|
524
|
+
currentAction: action,
|
|
525
|
+
invalidate
|
|
526
|
+
};
|
|
336
527
|
};
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
528
|
+
return {
|
|
529
|
+
state: {
|
|
530
|
+
isLoadingState: routerState.isLoadingState,
|
|
531
|
+
loaderFallbackState: routerState.loaderFallbackState,
|
|
532
|
+
routeItemDataState: routerState.routeItemDataState,
|
|
533
|
+
currentLoaderState: routerState.currentLoaderState,
|
|
534
|
+
scrollMapState: routerState.scrollMapState,
|
|
535
|
+
contextState: routerState.contextState,
|
|
536
|
+
blockedRouteState: routerState.blockedRouteState,
|
|
537
|
+
prevPathnameRef: routerState.prevPathnameRef
|
|
538
|
+
},
|
|
539
|
+
runtime: {
|
|
540
|
+
navigate,
|
|
541
|
+
invalidate,
|
|
542
|
+
prefetch
|
|
543
|
+
},
|
|
544
|
+
hooks: {
|
|
545
|
+
useIsLoading: () => useGlobalState(routerState.isLoadingState),
|
|
546
|
+
useBlockedRoute: () => useGlobalState(routerState.blockedRouteState),
|
|
547
|
+
useLoaderFallback: () => useGlobalState(routerState.loaderFallbackState),
|
|
548
|
+
useRouteItemData: () => useGlobalState(routerState.routeItemDataState),
|
|
549
|
+
useCurrentLoaderState: () => useGlobalState(routerState.currentLoaderState),
|
|
550
|
+
useScrollMap: () => useGlobalState(routerState.scrollMapState),
|
|
551
|
+
useContextState: () => useGlobalState(routerState.contextState),
|
|
552
|
+
useParams: () => {
|
|
553
|
+
const routeItemData = routerState.routeItemDataState.getState();
|
|
554
|
+
return getParamsObject({
|
|
555
|
+
params: routeItemData.routeItem?.params,
|
|
556
|
+
pathname: routeItemData.location.pathname
|
|
557
|
+
});
|
|
558
|
+
},
|
|
559
|
+
useNavigate: () => {
|
|
560
|
+
const { blockedRouteState } = routerState;
|
|
561
|
+
const { location } = routerState.routeItemDataState.getState();
|
|
562
|
+
return async (arg) => {
|
|
563
|
+
if (arg !== -1 && blockedRouteState.getState().from) {
|
|
564
|
+
const to = typeof arg === "object" ? arg.pathname : arg;
|
|
565
|
+
blockedRouteState.setState((prevState) => ({
|
|
566
|
+
...prevState,
|
|
567
|
+
to
|
|
568
|
+
}));
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
if (arg === -1) return history.go(arg);
|
|
572
|
+
if (typeof arg === "string") {
|
|
573
|
+
if (arg !== location.pathname) await navigate({ pathname: arg });
|
|
574
|
+
} else if (JSON.stringify(arg) !== JSON.stringify(location)) await navigate(arg);
|
|
575
|
+
};
|
|
576
|
+
},
|
|
577
|
+
useRestoreScroll: () => {
|
|
578
|
+
const { pathname } = routerState.routeItemDataState.getState().location;
|
|
579
|
+
const scrollMap = routerState.scrollMapState.getState();
|
|
580
|
+
return () => {
|
|
581
|
+
if (scrollMap[pathname]) requestAnimationFrame(() => window.scrollTo({
|
|
582
|
+
top: scrollMap[pathname],
|
|
583
|
+
behavior: "smooth"
|
|
584
|
+
}));
|
|
585
|
+
};
|
|
586
|
+
},
|
|
587
|
+
useGetAction,
|
|
588
|
+
useAction: (action, options = {}) => {
|
|
589
|
+
const { currentAction, invalidate } = useGetAction(action);
|
|
590
|
+
return async (formData) => {
|
|
591
|
+
try {
|
|
592
|
+
const result = await currentAction(formData);
|
|
593
|
+
await invalidate();
|
|
594
|
+
options.onSuccess?.(result);
|
|
595
|
+
} catch (error) {
|
|
596
|
+
options.onError?.(error);
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
357
600
|
}
|
|
358
601
|
};
|
|
359
|
-
if (beforeLoad) await runBeforeLoad(beforeLoad);
|
|
360
|
-
if (routeItem?.beforeLoad) await runBeforeLoad(routeItem?.beforeLoad);
|
|
361
|
-
};
|
|
362
|
-
var prepareNavigation = (routeItem, location) => {
|
|
363
|
-
const { isAnimated, showFallbackOnAnimation: showFallback } = routerConfig;
|
|
364
|
-
scrollMapState.setState((prevState) => {
|
|
365
|
-
const scrollPosition = document.scrollingElement?.scrollTop ?? 0;
|
|
366
|
-
if (!scrollPosition || prevState[prevPathnameRef.value] === scrollPosition) return prevState;
|
|
367
|
-
return {
|
|
368
|
-
...prevState,
|
|
369
|
-
[prevPathnameRef.value]: scrollPosition
|
|
370
|
-
};
|
|
371
|
-
});
|
|
372
|
-
loaderFallbackState.setState(isCacheItemFresh({
|
|
373
|
-
routeItem,
|
|
374
|
-
pathname: location.pathname
|
|
375
|
-
}) || isAnimated && !showFallback ? void 0 : routeItem?.loaderFallback);
|
|
376
|
-
};
|
|
377
|
-
var loader = async (routeItem, location) => {
|
|
378
|
-
if (!routeItem?.loader) return;
|
|
379
|
-
isLoadingState.setState(true);
|
|
380
|
-
await revalidateCache({
|
|
381
|
-
routeItem,
|
|
382
|
-
pathname: location.pathname
|
|
383
|
-
});
|
|
384
|
-
};
|
|
385
|
-
var afterLoad = async (routeItem, params) => {
|
|
386
|
-
const { afterLoad } = routerConfig;
|
|
387
|
-
if (routeItem?.afterLoad) await routeItem.afterLoad({
|
|
388
|
-
...getContext(),
|
|
389
|
-
params
|
|
390
|
-
});
|
|
391
|
-
if (afterLoad) await afterLoad({
|
|
392
|
-
...getContext(),
|
|
393
|
-
params
|
|
394
|
-
});
|
|
395
|
-
};
|
|
396
|
-
var navigate = async (nextLocation) => {
|
|
397
|
-
navigationSeq = navigationSeq + 1;
|
|
398
|
-
const seq = navigationSeq;
|
|
399
|
-
const { nextItem, params } = routeResolve(nextLocation);
|
|
400
|
-
await beforeLoad(nextItem, params);
|
|
401
|
-
if (seq !== navigationSeq) return;
|
|
402
|
-
prepareNavigation(nextItem, nextLocation);
|
|
403
|
-
await loader(nextItem, nextLocation);
|
|
404
|
-
if (seq !== navigationSeq) return;
|
|
405
|
-
commitNavigation(nextLocation, nextItem);
|
|
406
|
-
await afterLoad(nextItem, params);
|
|
407
602
|
};
|
|
408
603
|
//#endregion
|
|
604
|
+
//#region instance.ts
|
|
605
|
+
var router = createRouterInstance();
|
|
606
|
+
//#endregion
|
|
409
607
|
//#region hooks/useNavigation.ts
|
|
410
608
|
var useNavigation = () => {
|
|
411
|
-
const
|
|
609
|
+
const { state: { prevPathnameRef, blockedRouteState }, runtime: { navigate } } = router;
|
|
412
610
|
useEffect(() => {
|
|
413
611
|
const handler = async (event) => {
|
|
414
612
|
const newLocation = parseWindowLocation(event.target.location);
|
|
415
|
-
if (prevPathnameRef.value ===
|
|
416
|
-
|
|
613
|
+
if (prevPathnameRef.value === blockedRouteState.getState().from) {
|
|
614
|
+
blockedRouteState.setState({
|
|
417
615
|
from: prevPathnameRef.value,
|
|
418
616
|
to: newLocation.pathname
|
|
419
617
|
});
|
|
@@ -422,12 +620,16 @@ var useNavigation = () => {
|
|
|
422
620
|
};
|
|
423
621
|
window.addEventListener("popstate", handler);
|
|
424
622
|
return () => window.removeEventListener("popstate", handler);
|
|
425
|
-
}, [
|
|
623
|
+
}, [
|
|
624
|
+
blockedRouteState,
|
|
625
|
+
navigate,
|
|
626
|
+
prevPathnameRef.value
|
|
627
|
+
]);
|
|
426
628
|
useEffect(() => {
|
|
427
629
|
const currentLocation = parseWindowLocation(window.location);
|
|
428
630
|
navigate(currentLocation);
|
|
429
631
|
prevPathnameRef.set(currentLocation.pathname);
|
|
430
|
-
}, []);
|
|
632
|
+
}, [navigate, prevPathnameRef]);
|
|
431
633
|
};
|
|
432
634
|
//#endregion
|
|
433
635
|
//#region hooks/useApplyCustomAnimation.ts
|
|
@@ -467,20 +669,16 @@ var useApplyCustomAnimation = (animationDuration) => {
|
|
|
467
669
|
}, [animationDuration]);
|
|
468
670
|
};
|
|
469
671
|
//#endregion
|
|
672
|
+
//#region hooks/useLocation.ts
|
|
673
|
+
var useLocation = () => {
|
|
674
|
+
const [routeItemData] = router.hooks.useRouteItemData();
|
|
675
|
+
return routeItemData.location;
|
|
676
|
+
};
|
|
677
|
+
//#endregion
|
|
470
678
|
//#region hooks/usePreserveScroll.ts
|
|
471
679
|
var usePreserveScroll = (preserveScroll) => {
|
|
472
|
-
const
|
|
473
|
-
const
|
|
474
|
-
const { pathname } = routeItemData.location;
|
|
475
|
-
const restoreScroll = useCallback(() => {
|
|
476
|
-
if (!pathname || !scrollMap[pathname]) return;
|
|
477
|
-
requestAnimationFrame(() => {
|
|
478
|
-
window.scrollTo({
|
|
479
|
-
top: scrollMap[pathname],
|
|
480
|
-
behavior: "smooth"
|
|
481
|
-
});
|
|
482
|
-
});
|
|
483
|
-
}, [pathname, scrollMap]);
|
|
680
|
+
const restoreScroll = router.hooks.useRestoreScroll();
|
|
681
|
+
const { pathname } = useLocation();
|
|
484
682
|
useEffect(() => {
|
|
485
683
|
if (preserveScroll) restoreScroll();
|
|
486
684
|
}, [
|
|
@@ -497,7 +695,7 @@ var useSetRouterConfig = (routerProps) => {
|
|
|
497
695
|
//#endregion
|
|
498
696
|
//#region hooks/useSetInitialContext.ts
|
|
499
697
|
var useSetInitialContext = (initialContext) => {
|
|
500
|
-
const [, setContext] = useContextState();
|
|
698
|
+
const [, setContext] = router.hooks.useContextState();
|
|
501
699
|
useEffect(() => {
|
|
502
700
|
if (initialContext) setContext(initialContext);
|
|
503
701
|
}, [initialContext, setContext]);
|
|
@@ -514,7 +712,8 @@ var renderElement = (Component) => {
|
|
|
514
712
|
//#endregion
|
|
515
713
|
//#region components/Router.tsx
|
|
516
714
|
var EmptyBoundary = ({ children }) => children;
|
|
517
|
-
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 }) => {
|
|
715
|
+
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, defaultRetry }) => {
|
|
716
|
+
const { useIsLoading, useLoaderFallback, useRouteItemData, useCurrentLoaderState } = router.hooks;
|
|
518
717
|
const [isLoading] = useIsLoading();
|
|
519
718
|
const [currentLoaderFallback] = useLoaderFallback();
|
|
520
719
|
const [routeItemData] = useRouteItemData();
|
|
@@ -527,7 +726,8 @@ var Router = ({ routes, beforeLoad, afterLoad, animationDuration, isAnimated = f
|
|
|
527
726
|
hoverPrefetchDelay,
|
|
528
727
|
showFallbackOnAnimation,
|
|
529
728
|
beforeLoad,
|
|
530
|
-
afterLoad
|
|
729
|
+
afterLoad,
|
|
730
|
+
defaultRetry
|
|
531
731
|
});
|
|
532
732
|
useApplyCustomAnimation(animationDuration);
|
|
533
733
|
useSetInitialContext(initialContext);
|
|
@@ -546,98 +746,51 @@ var Router = ({ routes, beforeLoad, afterLoad, animationDuration, isAnimated = f
|
|
|
546
746
|
});
|
|
547
747
|
};
|
|
548
748
|
//#endregion
|
|
549
|
-
//#region runtime/prefetch.ts
|
|
550
|
-
var prefetch = async (pathname) => {
|
|
551
|
-
const item = findRoute(pathname);
|
|
552
|
-
if (item) await revalidateCache({
|
|
553
|
-
routeItem: item,
|
|
554
|
-
pathname
|
|
555
|
-
});
|
|
556
|
-
};
|
|
557
|
-
//#endregion
|
|
558
|
-
//#region hooks/useLocation.ts
|
|
559
|
-
var useLocation = () => {
|
|
560
|
-
const [routeItemData] = useRouteItemData();
|
|
561
|
-
return routeItemData.location;
|
|
562
|
-
};
|
|
563
|
-
//#endregion
|
|
564
|
-
//#region hooks/useLatest.ts
|
|
565
|
-
var useLatest = (value) => {
|
|
566
|
-
const ref = useRef(value);
|
|
567
|
-
useEffect(() => {
|
|
568
|
-
ref.current = value;
|
|
569
|
-
}, [value]);
|
|
570
|
-
return ref;
|
|
571
|
-
};
|
|
572
|
-
//#endregion
|
|
573
749
|
//#region hooks/useNavigate.ts
|
|
574
|
-
var useNavigate =
|
|
575
|
-
const [blockedRoute, setBlockedRoute] = useBlockedRoute();
|
|
576
|
-
const locationRef = useLatest(useLocation());
|
|
577
|
-
const blockedRouteRef = useLatest(blockedRoute);
|
|
578
|
-
return useCallback(async (arg) => {
|
|
579
|
-
if (!navigate) throw new Error("Router has not been initialized. Did you forget to render <Router />?");
|
|
580
|
-
if (arg !== -1 && blockedRouteRef.current.from) {
|
|
581
|
-
const to = typeof arg === "object" ? arg.pathname : arg;
|
|
582
|
-
setBlockedRoute((prevState) => ({
|
|
583
|
-
...prevState,
|
|
584
|
-
to
|
|
585
|
-
}));
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
if (arg === -1) return history.go(arg);
|
|
589
|
-
if (typeof arg === "string") {
|
|
590
|
-
if (arg !== locationRef.current.pathname) await navigate({ pathname: arg });
|
|
591
|
-
} else if (JSON.stringify(arg) !== JSON.stringify(locationRef.current)) await navigate(arg);
|
|
592
|
-
}, [
|
|
593
|
-
blockedRouteRef,
|
|
594
|
-
locationRef,
|
|
595
|
-
setBlockedRoute
|
|
596
|
-
]);
|
|
597
|
-
};
|
|
750
|
+
var useNavigate = router.hooks.useNavigate;
|
|
598
751
|
//#endregion
|
|
599
752
|
//#region components/Link.tsx
|
|
600
753
|
var Link = ({ children, to, prefetch: prefetchLink, hoverPrefetchDelay }) => {
|
|
601
754
|
const { prefetch: configPrefetch, hoverPrefetchDelay: configPrefetchDelay } = routerConfig;
|
|
602
|
-
const prefetch
|
|
755
|
+
const prefetch = prefetchLink || configPrefetch;
|
|
603
756
|
const prefetchDelay = hoverPrefetchDelay ?? configPrefetchDelay;
|
|
604
757
|
const navigate = useNavigate();
|
|
605
758
|
const timeout = useRef(0);
|
|
606
759
|
const ref = useRef(null);
|
|
607
760
|
const onMouseEnter = useCallback(() => {
|
|
608
|
-
if (prefetch
|
|
761
|
+
if (prefetch !== "hover" || !prefetchDelay) return;
|
|
609
762
|
if (timeout.current) clearTimeout(timeout.current);
|
|
610
|
-
timeout.current = window.setTimeout(() => prefetch(to), prefetchDelay);
|
|
763
|
+
timeout.current = window.setTimeout(() => router.runtime.prefetch(to), prefetchDelay);
|
|
611
764
|
}, [
|
|
612
|
-
prefetch
|
|
765
|
+
prefetch,
|
|
613
766
|
prefetchDelay,
|
|
614
767
|
to
|
|
615
768
|
]);
|
|
616
769
|
const onMouseLeave = useCallback(() => {
|
|
617
|
-
if (prefetch
|
|
770
|
+
if (prefetch !== "hover" || !prefetchDelay) return;
|
|
618
771
|
if (timeout.current) {
|
|
619
772
|
clearTimeout(timeout.current);
|
|
620
773
|
timeout.current = 0;
|
|
621
774
|
}
|
|
622
|
-
}, [prefetch
|
|
775
|
+
}, [prefetch, prefetchDelay]);
|
|
623
776
|
useEffect(() => {
|
|
624
|
-
if (prefetch
|
|
777
|
+
if (prefetch !== "render") return;
|
|
625
778
|
(async () => {
|
|
626
|
-
await prefetch(to);
|
|
779
|
+
await router.runtime.prefetch(to);
|
|
627
780
|
})();
|
|
628
|
-
}, [prefetch
|
|
781
|
+
}, [prefetch, to]);
|
|
629
782
|
useEffect(() => {
|
|
630
|
-
if (prefetch
|
|
783
|
+
if (prefetch !== "viewport") return;
|
|
631
784
|
const element = ref.current;
|
|
632
785
|
const observer = new IntersectionObserver(async () => {
|
|
633
|
-
await prefetch(to);
|
|
786
|
+
await router.runtime.prefetch(to);
|
|
634
787
|
observer.disconnect();
|
|
635
788
|
});
|
|
636
789
|
if (element) observer.observe(element);
|
|
637
790
|
return () => {
|
|
638
791
|
if (element) observer.disconnect();
|
|
639
792
|
};
|
|
640
|
-
}, [prefetch
|
|
793
|
+
}, [prefetch, to]);
|
|
641
794
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", {
|
|
642
795
|
ref,
|
|
643
796
|
style: { cursor: "pointer" },
|
|
@@ -657,97 +810,9 @@ var FormProvider = ({ children, isSubmitting }) => /* @__PURE__ */ (0, import_js
|
|
|
657
810
|
children
|
|
658
811
|
});
|
|
659
812
|
//#endregion
|
|
660
|
-
//#region runtime/invalidate.ts
|
|
661
|
-
var redirect = () => Promise.resolve();
|
|
662
|
-
var invalidatePath = async (routeItem, pathname) => {
|
|
663
|
-
const routePathname = routeItemDataState.getState().location.pathname;
|
|
664
|
-
timestampMap.delete(pathname);
|
|
665
|
-
const params = getParamsObject({
|
|
666
|
-
params: routeItem?.params,
|
|
667
|
-
pathname
|
|
668
|
-
});
|
|
669
|
-
try {
|
|
670
|
-
if (routeItem?.beforeLoad) {
|
|
671
|
-
const { context, setContext } = getContext();
|
|
672
|
-
await routeItem.beforeLoad({
|
|
673
|
-
context,
|
|
674
|
-
redirect,
|
|
675
|
-
params,
|
|
676
|
-
setContext
|
|
677
|
-
});
|
|
678
|
-
}
|
|
679
|
-
loaderStateRef.set((prev) => ({
|
|
680
|
-
...prev,
|
|
681
|
-
beforeLoadError: null
|
|
682
|
-
}));
|
|
683
|
-
} catch (error) {
|
|
684
|
-
loaderStateRef.set((prev) => ({
|
|
685
|
-
...prev,
|
|
686
|
-
beforeLoadError: error
|
|
687
|
-
}));
|
|
688
|
-
}
|
|
689
|
-
await revalidateCache({
|
|
690
|
-
routeItem,
|
|
691
|
-
pathname
|
|
692
|
-
});
|
|
693
|
-
if (pathname === routePathname) currentLoaderState.setState(loaderStateRef.value);
|
|
694
|
-
};
|
|
695
|
-
var invalidateItem = async (pathname, withChildren) => {
|
|
696
|
-
const routeItem = findRoute(pathname);
|
|
697
|
-
if (!routeItem) return;
|
|
698
|
-
const pathnameArray = [];
|
|
699
|
-
for (const [key] of timestampMap) if (comparePaths(routeItem, key)) pathnameArray.push(key);
|
|
700
|
-
await Promise.all(pathnameArray.map((pathname) => invalidatePath(routeItem, pathname)));
|
|
701
|
-
if (withChildren && routeItem.children?.length) {
|
|
702
|
-
const childPathList = routeItem.children.map((el) => el.path);
|
|
703
|
-
await Promise.all(childPathList.map((el) => invalidateItem(`${pathname}${el}`, withChildren)));
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
async function invalidate(pathList, options) {
|
|
707
|
-
const routePathname = routeItemDataState.getState().location.pathname;
|
|
708
|
-
const pathnameList = Array.isArray(pathList) ? pathList : pathList ? [pathList] : [routePathname];
|
|
709
|
-
await Promise.all(pathnameList.map((pathname) => invalidateItem(pathname, options?.withChildren)));
|
|
710
|
-
}
|
|
711
|
-
//#endregion
|
|
712
|
-
//#region hooks/useInvalidate.ts
|
|
713
|
-
var useInvalidate = () => invalidate;
|
|
714
|
-
//#endregion
|
|
715
|
-
//#region hooks/useParams.ts
|
|
716
|
-
var useParams = () => {
|
|
717
|
-
const [routeItemData] = useRouteItemData();
|
|
718
|
-
const { routeItem, location: { pathname } } = routeItemData;
|
|
719
|
-
return useMemo(() => routeItem ? getParamsObject({
|
|
720
|
-
params: routeItem?.params,
|
|
721
|
-
pathname
|
|
722
|
-
}) : void 0, [pathname, routeItem]);
|
|
723
|
-
};
|
|
724
|
-
//#endregion
|
|
725
|
-
//#region hooks/useGetAction.ts
|
|
726
|
-
var useGetAction = (actionKey) => {
|
|
727
|
-
const invalidate = useInvalidate();
|
|
728
|
-
const [routeItemData] = useRouteItemData();
|
|
729
|
-
const [context, setContext] = useContextState();
|
|
730
|
-
const params = useParams();
|
|
731
|
-
const { routeItem } = routeItemData;
|
|
732
|
-
const latestContext = useLatest(context);
|
|
733
|
-
if (!routeItem) throw new Error("Route not found");
|
|
734
|
-
if (!routeItem.actions) throw new Error("Route action creator not found");
|
|
735
|
-
const action = routeItem.actions({
|
|
736
|
-
context: latestContext.current,
|
|
737
|
-
setContext,
|
|
738
|
-
params,
|
|
739
|
-
invalidate
|
|
740
|
-
})[actionKey];
|
|
741
|
-
if (!action) throw new Error(`Action "${actionKey}" not found`);
|
|
742
|
-
return {
|
|
743
|
-
currentAction: action,
|
|
744
|
-
invalidate
|
|
745
|
-
};
|
|
746
|
-
};
|
|
747
|
-
//#endregion
|
|
748
813
|
//#region components/Form.tsx
|
|
749
814
|
var Form = ({ children, action, onSuccess, onError, autoReset = true }) => {
|
|
750
|
-
const { currentAction, invalidate } = useGetAction(action);
|
|
815
|
+
const { currentAction, invalidate } = router.hooks.useGetAction(action);
|
|
751
816
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
752
817
|
const onSubmit = async (evt) => {
|
|
753
818
|
evt.preventDefault();
|
|
@@ -772,14 +837,21 @@ var Form = ({ children, action, onSuccess, onError, autoReset = true }) => {
|
|
|
772
837
|
});
|
|
773
838
|
};
|
|
774
839
|
//#endregion
|
|
840
|
+
//#region hooks/useParams.ts
|
|
841
|
+
var useParams = router.hooks.useParams;
|
|
842
|
+
//#endregion
|
|
775
843
|
//#region hooks/useLoaderState.ts
|
|
776
844
|
var useLoaderState = () => {
|
|
777
|
-
const [loaderState] = useCurrentLoaderState();
|
|
845
|
+
const [loaderState] = router.hooks.useCurrentLoaderState();
|
|
778
846
|
return loaderState;
|
|
779
847
|
};
|
|
780
848
|
//#endregion
|
|
849
|
+
//#region hooks/useInvalidate.ts
|
|
850
|
+
var useInvalidate = () => router.runtime.invalidate;
|
|
851
|
+
//#endregion
|
|
781
852
|
//#region hooks/useBlocker.ts
|
|
782
853
|
var useBlocker = (blockerFn) => {
|
|
854
|
+
const { hooks: { useBlockedRoute, useRouteItemData }, runtime: { navigate } } = router;
|
|
783
855
|
const [blockedRoute, setBlockedRoute] = useBlockedRoute();
|
|
784
856
|
const [routeItemData] = useRouteItemData();
|
|
785
857
|
const { location: { pathname } } = routeItemData;
|
|
@@ -799,7 +871,7 @@ var useBlocker = (blockerFn) => {
|
|
|
799
871
|
from: "",
|
|
800
872
|
to: ""
|
|
801
873
|
};
|
|
802
|
-
}), [setBlockedRoute]);
|
|
874
|
+
}), [navigate, setBlockedRoute]);
|
|
803
875
|
const blockerState = useMemo(() => {
|
|
804
876
|
if (blockedRoute.from && blockedRoute.to) return "blocked";
|
|
805
877
|
if (blockedRoute.from) return "charged";
|
|
@@ -822,29 +894,11 @@ var useBlocker = (blockerFn) => {
|
|
|
822
894
|
};
|
|
823
895
|
//#endregion
|
|
824
896
|
//#region hooks/useAction.ts
|
|
825
|
-
var useAction =
|
|
826
|
-
const { currentAction, invalidate } = useGetAction(action);
|
|
827
|
-
const latestOnSuccess = useLatest(options?.onSuccess);
|
|
828
|
-
const latestOnError = useLatest(options?.onError);
|
|
829
|
-
return useCallback(async (formData) => {
|
|
830
|
-
try {
|
|
831
|
-
const result = await currentAction(formData);
|
|
832
|
-
await invalidate();
|
|
833
|
-
latestOnSuccess.current?.(result);
|
|
834
|
-
} catch (error) {
|
|
835
|
-
latestOnError.current?.(error);
|
|
836
|
-
}
|
|
837
|
-
}, [
|
|
838
|
-
currentAction,
|
|
839
|
-
invalidate,
|
|
840
|
-
latestOnError,
|
|
841
|
-
latestOnSuccess
|
|
842
|
-
]);
|
|
843
|
-
};
|
|
897
|
+
var useAction = router.hooks.useAction;
|
|
844
898
|
//#endregion
|
|
845
899
|
//#region hooks/useRouterContext.ts
|
|
846
900
|
var useRouterContext = () => {
|
|
847
|
-
const [context, setContext] = useContextState();
|
|
901
|
+
const [context, setContext] = router.hooks.useContextState();
|
|
848
902
|
return {
|
|
849
903
|
context,
|
|
850
904
|
setContext
|
|
@@ -880,6 +934,15 @@ var useSearch = () => {
|
|
|
880
934
|
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
881
935
|
};
|
|
882
936
|
//#endregion
|
|
937
|
+
//#region hooks/useLatest.ts
|
|
938
|
+
var useLatest = (value) => {
|
|
939
|
+
const ref = useRef(value);
|
|
940
|
+
useEffect(() => {
|
|
941
|
+
ref.current = value;
|
|
942
|
+
}, [value]);
|
|
943
|
+
return ref;
|
|
944
|
+
};
|
|
945
|
+
//#endregion
|
|
883
946
|
//#region hooks/useSearchParams.ts
|
|
884
947
|
var useSearchParams = () => {
|
|
885
948
|
const search = useSearch();
|