@tanstack/react-router 0.0.1-beta.234 → 0.0.1-beta.236
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/build/cjs/Matches.js +9 -8
- package/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +28 -31
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/router.js +49 -37
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +86 -76
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +566 -285
- package/build/types/router.d.ts +6 -3
- package/build/umd/index.development.js +354 -80
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -2
- package/build/umd/index.production.js.map +1 -1
- package/package.json +4 -2
- package/src/Matches.tsx +23 -10
- package/src/RouterProvider.tsx +35 -34
- package/src/router.ts +62 -44
package/build/types/router.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { RouterHistory } from '@tanstack/history';
|
|
4
|
+
import { Store } from '@tanstack/store';
|
|
4
5
|
import { AnySearchSchema, AnyRoute, AnyContext, AnyPathParams, RouteMask } from './route';
|
|
5
6
|
import { FullSearchSchema, RoutesById, RoutesByPath } from './routeInfo';
|
|
6
7
|
import { PickAsRequired, Updater, NonNullableUpdater } from './utils';
|
|
@@ -56,8 +57,10 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TDehydrated extends
|
|
|
56
57
|
}
|
|
57
58
|
export interface RouterState<TRouteTree extends AnyRoute = AnyRoute> {
|
|
58
59
|
status: 'pending' | 'idle';
|
|
60
|
+
isLoading: boolean;
|
|
61
|
+
isTransitioning: boolean;
|
|
59
62
|
matches: RouteMatch<TRouteTree>[];
|
|
60
|
-
pendingMatches
|
|
63
|
+
pendingMatches?: RouteMatch<TRouteTree>[];
|
|
61
64
|
location: ParsedLocation<FullSearchSchema<TRouteTree>>;
|
|
62
65
|
resolvedLocation: ParsedLocation<FullSearchSchema<TRouteTree>>;
|
|
63
66
|
lastUpdated: number;
|
|
@@ -122,7 +125,7 @@ export declare class Router<TRouteTree extends AnyRoute = AnyRoute, TDehydrated
|
|
|
122
125
|
pendingMatches: AnyRouteMatch[];
|
|
123
126
|
injectedHtml: InjectedHtmlEntry[];
|
|
124
127
|
dehydratedData?: TDehydrated;
|
|
125
|
-
|
|
128
|
+
__store: Store<RouterState<TRouteTree>>;
|
|
126
129
|
options: PickAsRequired<RouterOptions<TRouteTree, TDehydrated>, 'stringifySearch' | 'parseSearch' | 'context'>;
|
|
127
130
|
history: RouterHistory;
|
|
128
131
|
latestLocation: ParsedLocation;
|
|
@@ -133,8 +136,8 @@ export declare class Router<TRouteTree extends AnyRoute = AnyRoute, TDehydrated
|
|
|
133
136
|
flatRoutes: AnyRoute[];
|
|
134
137
|
constructor(options: RouterConstructorOptions<TRouteTree, TDehydrated>);
|
|
135
138
|
startReactTransition: (fn: () => void) => void;
|
|
136
|
-
setState: (updater: NonNullableUpdater<RouterState<TRouteTree>>) => void;
|
|
137
139
|
update: (newOptions: RouterConstructorOptions<TRouteTree, TDehydrated>) => void;
|
|
140
|
+
get state(): RouterState<TRouteTree>;
|
|
138
141
|
buildRouteTree: () => void;
|
|
139
142
|
subscribe: <TType extends keyof RouterEvents>(eventType: TType, fn: ListenerFn<RouterEvents[TType]>) => () => void;
|
|
140
143
|
emit: (routerEvent: RouterEvent) => void;
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
11
|
(function (global, factory) {
|
|
12
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
|
|
13
|
-
typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
|
|
14
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactRouter = {}, global.React));
|
|
15
|
-
})(this, (function (exports, React) { 'use strict';
|
|
12
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('use-sync-external-store/shim')) :
|
|
13
|
+
typeof define === 'function' && define.amd ? define(['exports', 'react', 'use-sync-external-store/shim'], factory) :
|
|
14
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactRouter = {}, global.React, global.require$$1));
|
|
15
|
+
})(this, (function (exports, React, require$$1) { 'use strict';
|
|
16
16
|
|
|
17
17
|
function _interopNamespaceDefault(e) {
|
|
18
18
|
var n = Object.create(null);
|
|
@@ -342,6 +342,272 @@
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
|
|
345
|
+
var withSelector = {exports: {}};
|
|
346
|
+
|
|
347
|
+
var withSelector_development = {};
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* @license React
|
|
351
|
+
* use-sync-external-store-shim/with-selector.development.js
|
|
352
|
+
*
|
|
353
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
354
|
+
*
|
|
355
|
+
* This source code is licensed under the MIT license found in the
|
|
356
|
+
* LICENSE file in the root directory of this source tree.
|
|
357
|
+
*/
|
|
358
|
+
|
|
359
|
+
var hasRequiredWithSelector_development;
|
|
360
|
+
|
|
361
|
+
function requireWithSelector_development () {
|
|
362
|
+
if (hasRequiredWithSelector_development) return withSelector_development;
|
|
363
|
+
hasRequiredWithSelector_development = 1;
|
|
364
|
+
|
|
365
|
+
{
|
|
366
|
+
(function() {
|
|
367
|
+
|
|
368
|
+
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
|
|
369
|
+
if (
|
|
370
|
+
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
|
|
371
|
+
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
|
|
372
|
+
'function'
|
|
373
|
+
) {
|
|
374
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
|
|
375
|
+
}
|
|
376
|
+
var React$1 = React;
|
|
377
|
+
var shim = require$$1;
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* inlined Object.is polyfill to avoid requiring consumers ship their own
|
|
381
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
|
|
382
|
+
*/
|
|
383
|
+
function is(x, y) {
|
|
384
|
+
return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
|
|
385
|
+
;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
var objectIs = typeof Object.is === 'function' ? Object.is : is;
|
|
389
|
+
|
|
390
|
+
var useSyncExternalStore = shim.useSyncExternalStore;
|
|
391
|
+
|
|
392
|
+
// for CommonJS interop.
|
|
393
|
+
|
|
394
|
+
var useRef = React$1.useRef,
|
|
395
|
+
useEffect = React$1.useEffect,
|
|
396
|
+
useMemo = React$1.useMemo,
|
|
397
|
+
useDebugValue = React$1.useDebugValue; // Same as useSyncExternalStore, but supports selector and isEqual arguments.
|
|
398
|
+
|
|
399
|
+
function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
|
|
400
|
+
// Use this to track the rendered snapshot.
|
|
401
|
+
var instRef = useRef(null);
|
|
402
|
+
var inst;
|
|
403
|
+
|
|
404
|
+
if (instRef.current === null) {
|
|
405
|
+
inst = {
|
|
406
|
+
hasValue: false,
|
|
407
|
+
value: null
|
|
408
|
+
};
|
|
409
|
+
instRef.current = inst;
|
|
410
|
+
} else {
|
|
411
|
+
inst = instRef.current;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
var _useMemo = useMemo(function () {
|
|
415
|
+
// Track the memoized state using closure variables that are local to this
|
|
416
|
+
// memoized instance of a getSnapshot function. Intentionally not using a
|
|
417
|
+
// useRef hook, because that state would be shared across all concurrent
|
|
418
|
+
// copies of the hook/component.
|
|
419
|
+
var hasMemo = false;
|
|
420
|
+
var memoizedSnapshot;
|
|
421
|
+
var memoizedSelection;
|
|
422
|
+
|
|
423
|
+
var memoizedSelector = function (nextSnapshot) {
|
|
424
|
+
if (!hasMemo) {
|
|
425
|
+
// The first time the hook is called, there is no memoized result.
|
|
426
|
+
hasMemo = true;
|
|
427
|
+
memoizedSnapshot = nextSnapshot;
|
|
428
|
+
|
|
429
|
+
var _nextSelection = selector(nextSnapshot);
|
|
430
|
+
|
|
431
|
+
if (isEqual !== undefined) {
|
|
432
|
+
// Even if the selector has changed, the currently rendered selection
|
|
433
|
+
// may be equal to the new selection. We should attempt to reuse the
|
|
434
|
+
// current value if possible, to preserve downstream memoizations.
|
|
435
|
+
if (inst.hasValue) {
|
|
436
|
+
var currentSelection = inst.value;
|
|
437
|
+
|
|
438
|
+
if (isEqual(currentSelection, _nextSelection)) {
|
|
439
|
+
memoizedSelection = currentSelection;
|
|
440
|
+
return currentSelection;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
memoizedSelection = _nextSelection;
|
|
446
|
+
return _nextSelection;
|
|
447
|
+
} // We may be able to reuse the previous invocation's result.
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
// We may be able to reuse the previous invocation's result.
|
|
451
|
+
var prevSnapshot = memoizedSnapshot;
|
|
452
|
+
var prevSelection = memoizedSelection;
|
|
453
|
+
|
|
454
|
+
if (objectIs(prevSnapshot, nextSnapshot)) {
|
|
455
|
+
// The snapshot is the same as last time. Reuse the previous selection.
|
|
456
|
+
return prevSelection;
|
|
457
|
+
} // The snapshot has changed, so we need to compute a new selection.
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
// The snapshot has changed, so we need to compute a new selection.
|
|
461
|
+
var nextSelection = selector(nextSnapshot); // If a custom isEqual function is provided, use that to check if the data
|
|
462
|
+
// has changed. If it hasn't, return the previous selection. That signals
|
|
463
|
+
// to React that the selections are conceptually equal, and we can bail
|
|
464
|
+
// out of rendering.
|
|
465
|
+
|
|
466
|
+
// If a custom isEqual function is provided, use that to check if the data
|
|
467
|
+
// has changed. If it hasn't, return the previous selection. That signals
|
|
468
|
+
// to React that the selections are conceptually equal, and we can bail
|
|
469
|
+
// out of rendering.
|
|
470
|
+
if (isEqual !== undefined && isEqual(prevSelection, nextSelection)) {
|
|
471
|
+
return prevSelection;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
memoizedSnapshot = nextSnapshot;
|
|
475
|
+
memoizedSelection = nextSelection;
|
|
476
|
+
return nextSelection;
|
|
477
|
+
}; // Assigning this to a constant so that Flow knows it can't change.
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
// Assigning this to a constant so that Flow knows it can't change.
|
|
481
|
+
var maybeGetServerSnapshot = getServerSnapshot === undefined ? null : getServerSnapshot;
|
|
482
|
+
|
|
483
|
+
var getSnapshotWithSelector = function () {
|
|
484
|
+
return memoizedSelector(getSnapshot());
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
var getServerSnapshotWithSelector = maybeGetServerSnapshot === null ? undefined : function () {
|
|
488
|
+
return memoizedSelector(maybeGetServerSnapshot());
|
|
489
|
+
};
|
|
490
|
+
return [getSnapshotWithSelector, getServerSnapshotWithSelector];
|
|
491
|
+
}, [getSnapshot, getServerSnapshot, selector, isEqual]),
|
|
492
|
+
getSelection = _useMemo[0],
|
|
493
|
+
getServerSelection = _useMemo[1];
|
|
494
|
+
|
|
495
|
+
var value = useSyncExternalStore(subscribe, getSelection, getServerSelection);
|
|
496
|
+
useEffect(function () {
|
|
497
|
+
inst.hasValue = true;
|
|
498
|
+
inst.value = value;
|
|
499
|
+
}, [value]);
|
|
500
|
+
useDebugValue(value);
|
|
501
|
+
return value;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
withSelector_development.useSyncExternalStoreWithSelector = useSyncExternalStoreWithSelector;
|
|
505
|
+
/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
|
|
506
|
+
if (
|
|
507
|
+
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
|
|
508
|
+
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
|
|
509
|
+
'function'
|
|
510
|
+
) {
|
|
511
|
+
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
})();
|
|
515
|
+
}
|
|
516
|
+
return withSelector_development;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
{
|
|
520
|
+
withSelector.exports = requireWithSelector_development();
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
var withSelectorExports = withSelector.exports;
|
|
524
|
+
|
|
525
|
+
// src/index.ts
|
|
526
|
+
var Store = class {
|
|
527
|
+
constructor(initialState, options) {
|
|
528
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
529
|
+
this._batching = false;
|
|
530
|
+
this._flushing = 0;
|
|
531
|
+
this._nextPriority = null;
|
|
532
|
+
this.subscribe = (listener) => {
|
|
533
|
+
this.listeners.add(listener);
|
|
534
|
+
const unsub = this.options?.onSubscribe?.(listener, this);
|
|
535
|
+
return () => {
|
|
536
|
+
this.listeners.delete(listener);
|
|
537
|
+
unsub?.();
|
|
538
|
+
};
|
|
539
|
+
};
|
|
540
|
+
this.setState = (updater, opts) => {
|
|
541
|
+
const previous = this.state;
|
|
542
|
+
this.state = this.options?.updateFn ? this.options.updateFn(previous)(updater) : updater(previous);
|
|
543
|
+
const priority = opts?.priority ?? this.options?.defaultPriority ?? "high";
|
|
544
|
+
if (this._nextPriority === null) {
|
|
545
|
+
this._nextPriority = priority;
|
|
546
|
+
} else if (this._nextPriority === "high") {
|
|
547
|
+
this._nextPriority = priority;
|
|
548
|
+
} else {
|
|
549
|
+
this._nextPriority = this.options?.defaultPriority ?? "high";
|
|
550
|
+
}
|
|
551
|
+
this.options?.onUpdate?.({
|
|
552
|
+
priority: this._nextPriority
|
|
553
|
+
});
|
|
554
|
+
this._flush();
|
|
555
|
+
};
|
|
556
|
+
this._flush = () => {
|
|
557
|
+
if (this._batching)
|
|
558
|
+
return;
|
|
559
|
+
const flushId = ++this._flushing;
|
|
560
|
+
this.listeners.forEach((listener) => {
|
|
561
|
+
if (this._flushing !== flushId)
|
|
562
|
+
return;
|
|
563
|
+
listener({
|
|
564
|
+
priority: this._nextPriority ?? "high"
|
|
565
|
+
});
|
|
566
|
+
});
|
|
567
|
+
};
|
|
568
|
+
this.batch = (cb) => {
|
|
569
|
+
if (this._batching)
|
|
570
|
+
return cb();
|
|
571
|
+
this._batching = true;
|
|
572
|
+
cb();
|
|
573
|
+
this._batching = false;
|
|
574
|
+
this._flush();
|
|
575
|
+
};
|
|
576
|
+
this.state = initialState;
|
|
577
|
+
this.options = options;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
// src/index.ts
|
|
582
|
+
function useStore(store, selector = (d) => d) {
|
|
583
|
+
const slice = withSelectorExports.useSyncExternalStoreWithSelector(
|
|
584
|
+
store.subscribe,
|
|
585
|
+
() => store.state,
|
|
586
|
+
() => store.state,
|
|
587
|
+
selector,
|
|
588
|
+
shallow$1
|
|
589
|
+
);
|
|
590
|
+
return slice;
|
|
591
|
+
}
|
|
592
|
+
function shallow$1(objA, objB) {
|
|
593
|
+
if (Object.is(objA, objB)) {
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
const keysA = Object.keys(objA);
|
|
600
|
+
if (keysA.length !== Object.keys(objB).length) {
|
|
601
|
+
return false;
|
|
602
|
+
}
|
|
603
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
604
|
+
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
|
|
605
|
+
return false;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
return true;
|
|
609
|
+
}
|
|
610
|
+
|
|
345
611
|
function CatchBoundary(props) {
|
|
346
612
|
const errorComponent = props.errorComponent ?? ErrorComponent;
|
|
347
613
|
return /*#__PURE__*/React__namespace.createElement(CatchBoundaryImpl, {
|
|
@@ -934,12 +1200,10 @@
|
|
|
934
1200
|
|
|
935
1201
|
function Matches() {
|
|
936
1202
|
const {
|
|
937
|
-
routesById
|
|
938
|
-
state
|
|
1203
|
+
routesById
|
|
939
1204
|
} = useRouter();
|
|
940
|
-
const
|
|
941
|
-
|
|
942
|
-
} = state;
|
|
1205
|
+
const routerState = useRouterState();
|
|
1206
|
+
const matches = routerState.pendingMatches?.some(d => d.showPending) ? routerState.pendingMatches : routerState.matches;
|
|
943
1207
|
const locationKey = useRouterState().location.state.key;
|
|
944
1208
|
const route = routesById[rootRouteId];
|
|
945
1209
|
const errorComponent = React__namespace.useCallback(props => {
|
|
@@ -1085,7 +1349,8 @@
|
|
|
1085
1349
|
const nearestMatchRouteId = nearestMatch?.routeId;
|
|
1086
1350
|
const matchRouteId = useRouterState({
|
|
1087
1351
|
select: state => {
|
|
1088
|
-
const
|
|
1352
|
+
const matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
|
|
1353
|
+
const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatch.id);
|
|
1089
1354
|
return match.routeId;
|
|
1090
1355
|
}
|
|
1091
1356
|
});
|
|
@@ -1094,7 +1359,8 @@
|
|
|
1094
1359
|
}
|
|
1095
1360
|
const matchSelection = useRouterState({
|
|
1096
1361
|
select: state => {
|
|
1097
|
-
const
|
|
1362
|
+
const matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
|
|
1363
|
+
const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatch.id);
|
|
1098
1364
|
invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
|
|
1099
1365
|
return opts?.select ? opts.select(match) : match;
|
|
1100
1366
|
}
|
|
@@ -1106,7 +1372,8 @@
|
|
|
1106
1372
|
const contextMatches = React__namespace.useContext(matchesContext);
|
|
1107
1373
|
return useRouterState({
|
|
1108
1374
|
select: state => {
|
|
1109
|
-
|
|
1375
|
+
let matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
|
|
1376
|
+
matches = matches.slice(matches.findIndex(d => d.id === contextMatches[0]?.id));
|
|
1110
1377
|
return opts?.select ? opts.select(matches) : matches;
|
|
1111
1378
|
}
|
|
1112
1379
|
});
|
|
@@ -1147,31 +1414,29 @@
|
|
|
1147
1414
|
function RouterProviderInner({
|
|
1148
1415
|
router
|
|
1149
1416
|
}) {
|
|
1150
|
-
const [preState, setState] = React__namespace.useState(() => router.state);
|
|
1151
1417
|
const [isTransitioning, startReactTransition] = React__namespace.useTransition();
|
|
1152
|
-
const isAnyTransitioning = isTransitioning || preState.matches.some(d => d.status === 'pending');
|
|
1153
|
-
const state = React__namespace.useMemo(() => ({
|
|
1154
|
-
...preState,
|
|
1155
|
-
status: isAnyTransitioning ? 'pending' : 'idle',
|
|
1156
|
-
location: isTransitioning ? router.latestLocation : preState.location,
|
|
1157
|
-
pendingMatches: router.pendingMatches
|
|
1158
|
-
}), [preState, isTransitioning]);
|
|
1159
|
-
router.setState = setState;
|
|
1160
|
-
router.state = state;
|
|
1161
1418
|
router.startReactTransition = startReactTransition;
|
|
1419
|
+
React__namespace.useEffect(() => {
|
|
1420
|
+
if (isTransitioning) {
|
|
1421
|
+
router.__store.setState(s => ({
|
|
1422
|
+
...s,
|
|
1423
|
+
isTransitioning
|
|
1424
|
+
}));
|
|
1425
|
+
}
|
|
1426
|
+
}, [isTransitioning]);
|
|
1162
1427
|
const tryLoad = () => {
|
|
1163
|
-
startReactTransition(() => {
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
})
|
|
1428
|
+
// startReactTransition(() => {
|
|
1429
|
+
try {
|
|
1430
|
+
router.load();
|
|
1431
|
+
} catch (err) {
|
|
1432
|
+
console.error(err);
|
|
1433
|
+
}
|
|
1434
|
+
// })
|
|
1170
1435
|
};
|
|
1171
1436
|
useLayoutEffect$1(() => {
|
|
1172
1437
|
const unsub = router.history.subscribe(() => {
|
|
1173
1438
|
router.latestLocation = router.parseLocation(router.latestLocation);
|
|
1174
|
-
if (state.location !== router.latestLocation) {
|
|
1439
|
+
if (router.state.location !== router.latestLocation) {
|
|
1175
1440
|
tryLoad();
|
|
1176
1441
|
}
|
|
1177
1442
|
});
|
|
@@ -1181,7 +1446,7 @@
|
|
|
1181
1446
|
hash: true,
|
|
1182
1447
|
state: true
|
|
1183
1448
|
});
|
|
1184
|
-
if (state.location.href !== nextLocation.href) {
|
|
1449
|
+
if (router.state.location.href !== nextLocation.href) {
|
|
1185
1450
|
router.commitLocation({
|
|
1186
1451
|
...nextLocation,
|
|
1187
1452
|
replace: true
|
|
@@ -1192,20 +1457,21 @@
|
|
|
1192
1457
|
};
|
|
1193
1458
|
}, [router.history]);
|
|
1194
1459
|
useLayoutEffect$1(() => {
|
|
1195
|
-
if (!isTransitioning && state.resolvedLocation !== state.location) {
|
|
1460
|
+
if (!isTransitioning && router.state.resolvedLocation !== router.state.location) {
|
|
1196
1461
|
router.emit({
|
|
1197
1462
|
type: 'onResolved',
|
|
1198
|
-
fromLocation: state.resolvedLocation,
|
|
1199
|
-
toLocation: state.location,
|
|
1200
|
-
pathChanged: state.location.href !== state.resolvedLocation?.href
|
|
1463
|
+
fromLocation: router.state.resolvedLocation,
|
|
1464
|
+
toLocation: router.state.location,
|
|
1465
|
+
pathChanged: router.state.location.href !== router.state.resolvedLocation?.href
|
|
1201
1466
|
});
|
|
1202
1467
|
router.pendingMatches = [];
|
|
1203
|
-
setState(s => ({
|
|
1468
|
+
router.__store.setState(s => ({
|
|
1204
1469
|
...s,
|
|
1470
|
+
isTransitioning: false,
|
|
1205
1471
|
resolvedLocation: s.location
|
|
1206
1472
|
}));
|
|
1207
1473
|
}
|
|
1208
|
-
});
|
|
1474
|
+
}, [isTransitioning]);
|
|
1209
1475
|
useLayoutEffect$1(() => {
|
|
1210
1476
|
if (!window.__TSR_DEHYDRATED__) {
|
|
1211
1477
|
tryLoad();
|
|
@@ -1216,14 +1482,11 @@
|
|
|
1216
1482
|
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
1217
1483
|
}
|
|
1218
1484
|
function getRouteMatch(state, id) {
|
|
1219
|
-
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
1485
|
+
return [...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
|
|
1220
1486
|
}
|
|
1221
1487
|
function useRouterState(opts) {
|
|
1222
|
-
const
|
|
1223
|
-
|
|
1224
|
-
} = useRouter();
|
|
1225
|
-
// return useStore(router.__store, opts?.select as any)
|
|
1226
|
-
return opts?.select ? opts.select(state) : state;
|
|
1488
|
+
const router = useRouter();
|
|
1489
|
+
return useStore(router.__store, opts?.select);
|
|
1227
1490
|
}
|
|
1228
1491
|
function useRouter() {
|
|
1229
1492
|
const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || routerContext : routerContext;
|
|
@@ -1586,9 +1849,6 @@
|
|
|
1586
1849
|
// by the router provider once rendered. We provide these so that the
|
|
1587
1850
|
// router can be used in a non-react environment if necessary
|
|
1588
1851
|
startReactTransition = fn => fn();
|
|
1589
|
-
setState = updater => {
|
|
1590
|
-
this.state = functionalUpdate(updater, this.state);
|
|
1591
|
-
};
|
|
1592
1852
|
update = newOptions => {
|
|
1593
1853
|
this.options = {
|
|
1594
1854
|
...this.options,
|
|
@@ -1603,10 +1863,20 @@
|
|
|
1603
1863
|
this.routeTree = this.options.routeTree;
|
|
1604
1864
|
this.buildRouteTree();
|
|
1605
1865
|
}
|
|
1606
|
-
if (!this.
|
|
1607
|
-
this.
|
|
1866
|
+
if (!this.__store) {
|
|
1867
|
+
this.__store = new Store(getInitialRouterState(this.latestLocation), {
|
|
1868
|
+
onUpdate: () => {
|
|
1869
|
+
this.__store.state = {
|
|
1870
|
+
...this.state,
|
|
1871
|
+
status: this.state.isTransitioning || this.state.isLoading ? 'pending' : 'idle'
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
});
|
|
1608
1875
|
}
|
|
1609
1876
|
};
|
|
1877
|
+
get state() {
|
|
1878
|
+
return this.__store.state;
|
|
1879
|
+
}
|
|
1610
1880
|
buildRouteTree = () => {
|
|
1611
1881
|
this.routesById = {};
|
|
1612
1882
|
this.routesByPath = {};
|
|
@@ -1878,7 +2148,7 @@
|
|
|
1878
2148
|
getRouteMatch(this.state, id)?.abortController?.abort();
|
|
1879
2149
|
};
|
|
1880
2150
|
cancelMatches = () => {
|
|
1881
|
-
this.state.
|
|
2151
|
+
this.state.pendingMatches?.forEach(match => {
|
|
1882
2152
|
this.cancelMatch(match.id);
|
|
1883
2153
|
});
|
|
1884
2154
|
};
|
|
@@ -2069,6 +2339,12 @@
|
|
|
2069
2339
|
}) => {
|
|
2070
2340
|
let latestPromise;
|
|
2071
2341
|
let firstBadMatchIndex;
|
|
2342
|
+
const updatePendingMatch = match => {
|
|
2343
|
+
this.__store.setState(s => ({
|
|
2344
|
+
...s,
|
|
2345
|
+
pendingMatches: s.pendingMatches?.map(d => d.id === match.id ? match : d)
|
|
2346
|
+
}));
|
|
2347
|
+
};
|
|
2072
2348
|
|
|
2073
2349
|
// Check each match middleware to see if the route can be accessed
|
|
2074
2350
|
try {
|
|
@@ -2225,12 +2501,10 @@
|
|
|
2225
2501
|
loadPromise
|
|
2226
2502
|
};
|
|
2227
2503
|
if (!preload) {
|
|
2228
|
-
|
|
2229
|
-
...s,
|
|
2230
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2231
|
-
}));
|
|
2504
|
+
updatePendingMatch(match);
|
|
2232
2505
|
}
|
|
2233
2506
|
let didShowPending = false;
|
|
2507
|
+
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2234
2508
|
await new Promise(async resolve => {
|
|
2235
2509
|
// If the route has a pending component and a pendingMs option,
|
|
2236
2510
|
// forcefully show the pending component
|
|
@@ -2242,17 +2516,13 @@
|
|
|
2242
2516
|
...match,
|
|
2243
2517
|
showPending: true
|
|
2244
2518
|
};
|
|
2245
|
-
|
|
2246
|
-
...s,
|
|
2247
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2248
|
-
}));
|
|
2519
|
+
updatePendingMatch(match);
|
|
2249
2520
|
resolve();
|
|
2250
2521
|
});
|
|
2251
2522
|
}
|
|
2252
2523
|
try {
|
|
2253
2524
|
const loaderData = await loadPromise;
|
|
2254
2525
|
if (latestPromise = checkLatest()) return await latestPromise;
|
|
2255
|
-
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2256
2526
|
if (didShowPending && pendingMinMs) {
|
|
2257
2527
|
await new Promise(r => setTimeout(r, pendingMinMs));
|
|
2258
2528
|
}
|
|
@@ -2282,12 +2552,19 @@
|
|
|
2282
2552
|
isFetching: false,
|
|
2283
2553
|
updatedAt: Date.now()
|
|
2284
2554
|
};
|
|
2555
|
+
} finally {
|
|
2556
|
+
// If we showed the pending component, that means
|
|
2557
|
+
// we already moved the pendingMatches to the matches
|
|
2558
|
+
// state, so we need to update that specific match
|
|
2559
|
+
if (didShowPending && pendingMinMs && match.showPending) {
|
|
2560
|
+
this.__store.setState(s => ({
|
|
2561
|
+
...s,
|
|
2562
|
+
matches: s.matches?.map(d => d.id === match.id ? match : d)
|
|
2563
|
+
}));
|
|
2564
|
+
}
|
|
2285
2565
|
}
|
|
2286
2566
|
if (!preload) {
|
|
2287
|
-
|
|
2288
|
-
...s,
|
|
2289
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2290
|
-
}));
|
|
2567
|
+
updatePendingMatch(match);
|
|
2291
2568
|
}
|
|
2292
2569
|
resolve();
|
|
2293
2570
|
});
|
|
@@ -2316,24 +2593,23 @@
|
|
|
2316
2593
|
});
|
|
2317
2594
|
|
|
2318
2595
|
// Match the routes
|
|
2319
|
-
let
|
|
2596
|
+
let pendingMatches = this.matchRoutes(next.pathname, next.search, {
|
|
2320
2597
|
debug: true
|
|
2321
2598
|
});
|
|
2322
|
-
this.pendingMatches = matches;
|
|
2323
2599
|
const previousMatches = this.state.matches;
|
|
2324
2600
|
|
|
2325
2601
|
// Ingest the new matches
|
|
2326
|
-
this.setState(s => ({
|
|
2602
|
+
this.__store.setState(s => ({
|
|
2327
2603
|
...s,
|
|
2328
|
-
|
|
2604
|
+
isLoading: true,
|
|
2329
2605
|
location: next,
|
|
2330
|
-
|
|
2606
|
+
pendingMatches
|
|
2331
2607
|
}));
|
|
2332
2608
|
try {
|
|
2333
2609
|
try {
|
|
2334
2610
|
// Load the matches
|
|
2335
2611
|
await this.loadMatches({
|
|
2336
|
-
matches,
|
|
2612
|
+
matches: pendingMatches,
|
|
2337
2613
|
checkLatest: () => this.checkLatest(promise),
|
|
2338
2614
|
invalidate: opts?.invalidate
|
|
2339
2615
|
});
|
|
@@ -2348,14 +2624,13 @@
|
|
|
2348
2624
|
}
|
|
2349
2625
|
const exitingMatchIds = previousMatches.filter(id => !this.pendingMatches.includes(id));
|
|
2350
2626
|
const enteringMatchIds = this.pendingMatches.filter(id => !previousMatches.includes(id));
|
|
2351
|
-
const stayingMatchIds = previousMatches.filter(id => this.pendingMatches.includes(id))
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
// }))
|
|
2627
|
+
const stayingMatchIds = previousMatches.filter(id => this.pendingMatches.includes(id));
|
|
2628
|
+
this.__store.setState(s => ({
|
|
2629
|
+
...s,
|
|
2630
|
+
isLoading: false,
|
|
2631
|
+
matches: pendingMatches,
|
|
2632
|
+
pendingMatches: undefined
|
|
2633
|
+
}))
|
|
2359
2634
|
|
|
2360
2635
|
//
|
|
2361
2636
|
;
|
|
@@ -2510,9 +2785,6 @@
|
|
|
2510
2785
|
return false;
|
|
2511
2786
|
}
|
|
2512
2787
|
const baseLocation = opts?.pending ? this.latestLocation : this.state.resolvedLocation;
|
|
2513
|
-
|
|
2514
|
-
// const baseLocation = state.resolvedLocation
|
|
2515
|
-
|
|
2516
2788
|
if (!baseLocation) {
|
|
2517
2789
|
return false;
|
|
2518
2790
|
}
|
|
@@ -2584,7 +2856,7 @@
|
|
|
2584
2856
|
}
|
|
2585
2857
|
return match;
|
|
2586
2858
|
});
|
|
2587
|
-
this.setState(s => {
|
|
2859
|
+
this.__store.setState(s => {
|
|
2588
2860
|
return {
|
|
2589
2861
|
...s,
|
|
2590
2862
|
matches: matches
|
|
@@ -2615,6 +2887,8 @@
|
|
|
2615
2887
|
class PathParamError extends Error {}
|
|
2616
2888
|
function getInitialRouterState(location) {
|
|
2617
2889
|
return {
|
|
2890
|
+
isLoading: false,
|
|
2891
|
+
isTransitioning: false,
|
|
2618
2892
|
status: 'idle',
|
|
2619
2893
|
resolvedLocation: location,
|
|
2620
2894
|
location,
|