@tanstack/react-router 0.0.1-beta.235 → 0.0.1-beta.237
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 +31 -18
- package/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +45 -25
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/index.js +1 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/route.js +13 -7
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +49 -37
- package/build/cjs/router.js.map +1 -1
- package/build/cjs/useParams.js +7 -2
- package/build/cjs/useParams.js.map +1 -1
- package/build/cjs/useSearch.js +6 -1
- package/build/cjs/useSearch.js.map +1 -1
- package/build/cjs/utils.js +4 -1
- package/build/cjs/utils.js.map +1 -1
- package/build/esm/index.js +155 -92
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +574 -293
- package/build/types/Matches.d.ts +9 -3
- package/build/types/RouterProvider.d.ts +3 -0
- package/build/types/route.d.ts +30 -10
- package/build/types/router.d.ts +6 -3
- package/build/types/useParams.d.ts +3 -1
- package/build/types/useSearch.d.ts +3 -1
- package/build/types/utils.d.ts +3 -1
- package/build/umd/index.development.js +423 -95
- 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 +70 -35
- package/src/RouterProvider.tsx +68 -32
- package/src/route.ts +37 -15
- package/src/router.ts +62 -44
- package/src/useParams.tsx +14 -4
- package/src/useSearch.tsx +11 -3
- package/src/utils.ts +20 -12
|
@@ -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, {
|
|
@@ -608,7 +874,10 @@
|
|
|
608
874
|
return true;
|
|
609
875
|
}
|
|
610
876
|
function useRouteContext(opts) {
|
|
611
|
-
return useMatch(
|
|
877
|
+
return useMatch({
|
|
878
|
+
...opts,
|
|
879
|
+
select: match => opts?.select ? opts.select(match.context) : match.context
|
|
880
|
+
});
|
|
612
881
|
}
|
|
613
882
|
const useLayoutEffect$1 = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
|
|
614
883
|
function escapeJSON(jsonString) {
|
|
@@ -801,12 +1070,22 @@
|
|
|
801
1070
|
return isMatch ? params : undefined;
|
|
802
1071
|
}
|
|
803
1072
|
|
|
804
|
-
function useParams(
|
|
805
|
-
return
|
|
1073
|
+
function useParams(opts) {
|
|
1074
|
+
return useRouterState({
|
|
1075
|
+
select: state => {
|
|
1076
|
+
const params = last(state.matches)?.params;
|
|
1077
|
+
return opts?.select ? opts.select(params) : params;
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
806
1080
|
}
|
|
807
1081
|
|
|
808
1082
|
function useSearch(opts) {
|
|
809
|
-
return useMatch(
|
|
1083
|
+
return useMatch({
|
|
1084
|
+
...opts,
|
|
1085
|
+
select: match => {
|
|
1086
|
+
return opts?.select ? opts.select(match.search) : match.search;
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
810
1089
|
}
|
|
811
1090
|
|
|
812
1091
|
const rootRouteId = '__root__';
|
|
@@ -871,28 +1150,34 @@
|
|
|
871
1150
|
// This is a dummy static method that should get
|
|
872
1151
|
// replaced by a framework specific implementation if necessary
|
|
873
1152
|
};
|
|
874
|
-
useMatch =
|
|
1153
|
+
useMatch = opts => {
|
|
875
1154
|
return useMatch({
|
|
1155
|
+
...opts,
|
|
876
1156
|
from: this.id
|
|
877
1157
|
});
|
|
878
1158
|
};
|
|
879
|
-
useRouteContext =
|
|
1159
|
+
useRouteContext = opts => {
|
|
880
1160
|
return useMatch({
|
|
881
|
-
|
|
882
|
-
|
|
1161
|
+
...opts,
|
|
1162
|
+
from: this.id,
|
|
1163
|
+
select: d => opts?.select ? opts.select(d.context) : d.context
|
|
1164
|
+
});
|
|
883
1165
|
};
|
|
884
|
-
useSearch =
|
|
1166
|
+
useSearch = opts => {
|
|
885
1167
|
return useSearch({
|
|
1168
|
+
...opts,
|
|
886
1169
|
from: this.id
|
|
887
1170
|
});
|
|
888
1171
|
};
|
|
889
|
-
useParams =
|
|
1172
|
+
useParams = opts => {
|
|
890
1173
|
return useParams({
|
|
1174
|
+
...opts,
|
|
891
1175
|
from: this.id
|
|
892
1176
|
});
|
|
893
1177
|
};
|
|
894
|
-
useLoaderData =
|
|
1178
|
+
useLoaderData = opts => {
|
|
895
1179
|
return useLoaderData({
|
|
1180
|
+
...opts,
|
|
896
1181
|
from: this.id
|
|
897
1182
|
});
|
|
898
1183
|
};
|
|
@@ -915,10 +1200,9 @@
|
|
|
915
1200
|
|
|
916
1201
|
function Matches() {
|
|
917
1202
|
const router = useRouter();
|
|
918
|
-
const
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
const locationKey = router.state.location.state.key;
|
|
1203
|
+
const routerState = useRouterState();
|
|
1204
|
+
const matches = routerState.pendingMatches?.some(d => d.showPending) ? routerState.pendingMatches : routerState.matches;
|
|
1205
|
+
const locationKey = router.latestLocation.state.key;
|
|
922
1206
|
const route = router.routesById[rootRouteId];
|
|
923
1207
|
const errorComponent = React__namespace.useCallback(props => {
|
|
924
1208
|
return /*#__PURE__*/React__namespace.createElement(ErrorComponent, {
|
|
@@ -1059,31 +1343,45 @@
|
|
|
1059
1343
|
return !!params ? props.children : null;
|
|
1060
1344
|
}
|
|
1061
1345
|
function useMatch(opts) {
|
|
1062
|
-
const router = useRouter();
|
|
1063
1346
|
const nearestMatch = React__namespace.useContext(matchesContext)[0];
|
|
1064
1347
|
const nearestMatchRouteId = nearestMatch?.routeId;
|
|
1065
|
-
const matchRouteId = (
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1348
|
+
const matchRouteId = useRouterState({
|
|
1349
|
+
select: state => {
|
|
1350
|
+
const matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
|
|
1351
|
+
const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatch.id);
|
|
1352
|
+
return match.routeId;
|
|
1353
|
+
}
|
|
1354
|
+
});
|
|
1069
1355
|
if (opts?.strict ?? true) {
|
|
1070
1356
|
invariant(nearestMatchRouteId == matchRouteId, `useMatch("${matchRouteId}") is being called in a component that is meant to render the '${nearestMatchRouteId}' route. Did you mean to 'useMatch("${matchRouteId}", { strict: false })' or 'useRoute("${matchRouteId}")' instead?`);
|
|
1071
1357
|
}
|
|
1072
|
-
const matchSelection = (
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1358
|
+
const matchSelection = useRouterState({
|
|
1359
|
+
select: state => {
|
|
1360
|
+
const matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
|
|
1361
|
+
const match = opts?.from ? matches.find(d => d.routeId === opts?.from) : matches.find(d => d.id === nearestMatch.id);
|
|
1362
|
+
invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
|
|
1363
|
+
return opts?.select ? opts.select(match) : match;
|
|
1364
|
+
}
|
|
1365
|
+
});
|
|
1077
1366
|
return matchSelection;
|
|
1078
1367
|
}
|
|
1079
1368
|
const matchesContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
1080
|
-
function useMatches() {
|
|
1081
|
-
const router = useRouter();
|
|
1369
|
+
function useMatches(opts) {
|
|
1082
1370
|
const contextMatches = React__namespace.useContext(matchesContext);
|
|
1083
|
-
return
|
|
1371
|
+
return useRouterState({
|
|
1372
|
+
select: state => {
|
|
1373
|
+
let matches = state.pendingMatches?.some(d => d.showPending) ? state.pendingMatches : state.matches;
|
|
1374
|
+
matches = matches.slice(matches.findIndex(d => d.id === contextMatches[0]?.id));
|
|
1375
|
+
return opts?.select ? opts.select(matches) : matches;
|
|
1376
|
+
}
|
|
1377
|
+
});
|
|
1084
1378
|
}
|
|
1085
1379
|
function useLoaderData(opts) {
|
|
1086
|
-
|
|
1380
|
+
const match = useMatch({
|
|
1381
|
+
...opts,
|
|
1382
|
+
select: undefined
|
|
1383
|
+
});
|
|
1384
|
+
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
1087
1385
|
}
|
|
1088
1386
|
|
|
1089
1387
|
const routerContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
@@ -1103,9 +1401,11 @@
|
|
|
1103
1401
|
...rest?.context
|
|
1104
1402
|
}
|
|
1105
1403
|
});
|
|
1106
|
-
const inner = /*#__PURE__*/React__namespace.createElement(
|
|
1404
|
+
const inner = /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
|
|
1405
|
+
value: router
|
|
1406
|
+
}, /*#__PURE__*/React__namespace.createElement(RouterProviderInner, {
|
|
1107
1407
|
router: router
|
|
1108
|
-
});
|
|
1408
|
+
}));
|
|
1109
1409
|
if (router.options.Wrap) {
|
|
1110
1410
|
return /*#__PURE__*/React__namespace.createElement(router.options.Wrap, null, inner);
|
|
1111
1411
|
}
|
|
@@ -1114,20 +1414,32 @@
|
|
|
1114
1414
|
function RouterProviderInner({
|
|
1115
1415
|
router
|
|
1116
1416
|
}) {
|
|
1117
|
-
|
|
1417
|
+
return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Matches, null), /*#__PURE__*/React__namespace.createElement(Transitioner, null));
|
|
1418
|
+
}
|
|
1419
|
+
function Transitioner() {
|
|
1420
|
+
const router = useRouter();
|
|
1421
|
+
const routerState = useRouterState({
|
|
1422
|
+
select: s => pick(s, ['isLoading', 'location', 'resolvedLocation', 'isTransitioning'])
|
|
1423
|
+
});
|
|
1118
1424
|
const [isTransitioning, startReactTransition] = React__namespace.useTransition();
|
|
1119
|
-
const isAnyTransitioning = isTransitioning || preState.matches.some(d => d.status === 'pending');
|
|
1120
|
-
const state = React__namespace.useMemo(() => ({
|
|
1121
|
-
...preState,
|
|
1122
|
-
status: isAnyTransitioning ? 'pending' : 'idle',
|
|
1123
|
-
location: isTransitioning ? router.latestLocation : preState.location,
|
|
1124
|
-
pendingMatches: router.pendingMatches
|
|
1125
|
-
}), [preState, isTransitioning]);
|
|
1126
|
-
router.setState = setState;
|
|
1127
|
-
router.state = state;
|
|
1128
1425
|
router.startReactTransition = startReactTransition;
|
|
1426
|
+
React__namespace.useEffect(() => {
|
|
1427
|
+
if (isTransitioning) {
|
|
1428
|
+
router.__store.setState(s => ({
|
|
1429
|
+
...s,
|
|
1430
|
+
isTransitioning
|
|
1431
|
+
}));
|
|
1432
|
+
}
|
|
1433
|
+
}, [isTransitioning]);
|
|
1129
1434
|
const tryLoad = () => {
|
|
1130
|
-
|
|
1435
|
+
const apply = cb => {
|
|
1436
|
+
if (!routerState.isTransitioning) {
|
|
1437
|
+
startReactTransition(() => cb());
|
|
1438
|
+
} else {
|
|
1439
|
+
cb();
|
|
1440
|
+
}
|
|
1441
|
+
};
|
|
1442
|
+
apply(() => {
|
|
1131
1443
|
try {
|
|
1132
1444
|
router.load();
|
|
1133
1445
|
} catch (err) {
|
|
@@ -1138,7 +1450,7 @@
|
|
|
1138
1450
|
useLayoutEffect$1(() => {
|
|
1139
1451
|
const unsub = router.history.subscribe(() => {
|
|
1140
1452
|
router.latestLocation = router.parseLocation(router.latestLocation);
|
|
1141
|
-
if (
|
|
1453
|
+
if (routerState.location !== router.latestLocation) {
|
|
1142
1454
|
tryLoad();
|
|
1143
1455
|
}
|
|
1144
1456
|
});
|
|
@@ -1148,7 +1460,7 @@
|
|
|
1148
1460
|
hash: true,
|
|
1149
1461
|
state: true
|
|
1150
1462
|
});
|
|
1151
|
-
if (
|
|
1463
|
+
if (routerState.location.href !== nextLocation.href) {
|
|
1152
1464
|
router.commitLocation({
|
|
1153
1465
|
...nextLocation,
|
|
1154
1466
|
replace: true
|
|
@@ -1159,31 +1471,35 @@
|
|
|
1159
1471
|
};
|
|
1160
1472
|
}, [router.history]);
|
|
1161
1473
|
useLayoutEffect$1(() => {
|
|
1162
|
-
if (!isTransitioning &&
|
|
1474
|
+
if (!isTransitioning && !routerState.isLoading && routerState.resolvedLocation !== routerState.location) {
|
|
1475
|
+
console.log('onResolved', routerState.location);
|
|
1163
1476
|
router.emit({
|
|
1164
1477
|
type: 'onResolved',
|
|
1165
|
-
fromLocation:
|
|
1166
|
-
toLocation:
|
|
1167
|
-
pathChanged:
|
|
1478
|
+
fromLocation: routerState.resolvedLocation,
|
|
1479
|
+
toLocation: routerState.location,
|
|
1480
|
+
pathChanged: routerState.location.href !== routerState.resolvedLocation?.href
|
|
1168
1481
|
});
|
|
1169
1482
|
router.pendingMatches = [];
|
|
1170
|
-
setState(s => ({
|
|
1483
|
+
router.__store.setState(s => ({
|
|
1171
1484
|
...s,
|
|
1485
|
+
isTransitioning: false,
|
|
1172
1486
|
resolvedLocation: s.location
|
|
1173
1487
|
}));
|
|
1174
1488
|
}
|
|
1175
|
-
});
|
|
1489
|
+
}, [isTransitioning, routerState.isLoading]);
|
|
1176
1490
|
useLayoutEffect$1(() => {
|
|
1177
1491
|
if (!window.__TSR_DEHYDRATED__) {
|
|
1178
1492
|
tryLoad();
|
|
1179
1493
|
}
|
|
1180
1494
|
}, []);
|
|
1181
|
-
return
|
|
1182
|
-
value: router
|
|
1183
|
-
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
1495
|
+
return null;
|
|
1184
1496
|
}
|
|
1185
1497
|
function getRouteMatch(state, id) {
|
|
1186
|
-
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
1498
|
+
return [...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
|
|
1499
|
+
}
|
|
1500
|
+
function useRouterState(opts) {
|
|
1501
|
+
const router = useRouter();
|
|
1502
|
+
return useStore(router.__store, opts?.select);
|
|
1187
1503
|
}
|
|
1188
1504
|
function useRouter() {
|
|
1189
1505
|
const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || routerContext : routerContext;
|
|
@@ -1546,9 +1862,6 @@
|
|
|
1546
1862
|
// by the router provider once rendered. We provide these so that the
|
|
1547
1863
|
// router can be used in a non-react environment if necessary
|
|
1548
1864
|
startReactTransition = fn => fn();
|
|
1549
|
-
setState = updater => {
|
|
1550
|
-
this.state = functionalUpdate(updater, this.state);
|
|
1551
|
-
};
|
|
1552
1865
|
update = newOptions => {
|
|
1553
1866
|
this.options = {
|
|
1554
1867
|
...this.options,
|
|
@@ -1563,10 +1876,20 @@
|
|
|
1563
1876
|
this.routeTree = this.options.routeTree;
|
|
1564
1877
|
this.buildRouteTree();
|
|
1565
1878
|
}
|
|
1566
|
-
if (!this.
|
|
1567
|
-
this.
|
|
1879
|
+
if (!this.__store) {
|
|
1880
|
+
this.__store = new Store(getInitialRouterState(this.latestLocation), {
|
|
1881
|
+
onUpdate: () => {
|
|
1882
|
+
this.__store.state = {
|
|
1883
|
+
...this.state,
|
|
1884
|
+
status: this.state.isTransitioning || this.state.isLoading ? 'pending' : 'idle'
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
});
|
|
1568
1888
|
}
|
|
1569
1889
|
};
|
|
1890
|
+
get state() {
|
|
1891
|
+
return this.__store.state;
|
|
1892
|
+
}
|
|
1570
1893
|
buildRouteTree = () => {
|
|
1571
1894
|
this.routesById = {};
|
|
1572
1895
|
this.routesByPath = {};
|
|
@@ -1838,7 +2161,7 @@
|
|
|
1838
2161
|
getRouteMatch(this.state, id)?.abortController?.abort();
|
|
1839
2162
|
};
|
|
1840
2163
|
cancelMatches = () => {
|
|
1841
|
-
this.state.
|
|
2164
|
+
this.state.pendingMatches?.forEach(match => {
|
|
1842
2165
|
this.cancelMatch(match.id);
|
|
1843
2166
|
});
|
|
1844
2167
|
};
|
|
@@ -2029,6 +2352,12 @@
|
|
|
2029
2352
|
}) => {
|
|
2030
2353
|
let latestPromise;
|
|
2031
2354
|
let firstBadMatchIndex;
|
|
2355
|
+
const updatePendingMatch = match => {
|
|
2356
|
+
this.__store.setState(s => ({
|
|
2357
|
+
...s,
|
|
2358
|
+
pendingMatches: s.pendingMatches?.map(d => d.id === match.id ? match : d)
|
|
2359
|
+
}));
|
|
2360
|
+
};
|
|
2032
2361
|
|
|
2033
2362
|
// Check each match middleware to see if the route can be accessed
|
|
2034
2363
|
try {
|
|
@@ -2185,12 +2514,10 @@
|
|
|
2185
2514
|
loadPromise
|
|
2186
2515
|
};
|
|
2187
2516
|
if (!preload) {
|
|
2188
|
-
|
|
2189
|
-
...s,
|
|
2190
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2191
|
-
}));
|
|
2517
|
+
updatePendingMatch(match);
|
|
2192
2518
|
}
|
|
2193
2519
|
let didShowPending = false;
|
|
2520
|
+
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2194
2521
|
await new Promise(async resolve => {
|
|
2195
2522
|
// If the route has a pending component and a pendingMs option,
|
|
2196
2523
|
// forcefully show the pending component
|
|
@@ -2202,17 +2529,13 @@
|
|
|
2202
2529
|
...match,
|
|
2203
2530
|
showPending: true
|
|
2204
2531
|
};
|
|
2205
|
-
|
|
2206
|
-
...s,
|
|
2207
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2208
|
-
}));
|
|
2532
|
+
updatePendingMatch(match);
|
|
2209
2533
|
resolve();
|
|
2210
2534
|
});
|
|
2211
2535
|
}
|
|
2212
2536
|
try {
|
|
2213
2537
|
const loaderData = await loadPromise;
|
|
2214
2538
|
if (latestPromise = checkLatest()) return await latestPromise;
|
|
2215
|
-
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2216
2539
|
if (didShowPending && pendingMinMs) {
|
|
2217
2540
|
await new Promise(r => setTimeout(r, pendingMinMs));
|
|
2218
2541
|
}
|
|
@@ -2242,12 +2565,19 @@
|
|
|
2242
2565
|
isFetching: false,
|
|
2243
2566
|
updatedAt: Date.now()
|
|
2244
2567
|
};
|
|
2568
|
+
} finally {
|
|
2569
|
+
// If we showed the pending component, that means
|
|
2570
|
+
// we already moved the pendingMatches to the matches
|
|
2571
|
+
// state, so we need to update that specific match
|
|
2572
|
+
if (didShowPending && pendingMinMs && match.showPending) {
|
|
2573
|
+
this.__store.setState(s => ({
|
|
2574
|
+
...s,
|
|
2575
|
+
matches: s.matches?.map(d => d.id === match.id ? match : d)
|
|
2576
|
+
}));
|
|
2577
|
+
}
|
|
2245
2578
|
}
|
|
2246
2579
|
if (!preload) {
|
|
2247
|
-
|
|
2248
|
-
...s,
|
|
2249
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2250
|
-
}));
|
|
2580
|
+
updatePendingMatch(match);
|
|
2251
2581
|
}
|
|
2252
2582
|
resolve();
|
|
2253
2583
|
});
|
|
@@ -2276,24 +2606,23 @@
|
|
|
2276
2606
|
});
|
|
2277
2607
|
|
|
2278
2608
|
// Match the routes
|
|
2279
|
-
let
|
|
2609
|
+
let pendingMatches = this.matchRoutes(next.pathname, next.search, {
|
|
2280
2610
|
debug: true
|
|
2281
2611
|
});
|
|
2282
|
-
this.pendingMatches = matches;
|
|
2283
2612
|
const previousMatches = this.state.matches;
|
|
2284
2613
|
|
|
2285
2614
|
// Ingest the new matches
|
|
2286
|
-
this.setState(s => ({
|
|
2615
|
+
this.__store.setState(s => ({
|
|
2287
2616
|
...s,
|
|
2288
|
-
|
|
2617
|
+
isLoading: true,
|
|
2289
2618
|
location: next,
|
|
2290
|
-
|
|
2619
|
+
pendingMatches
|
|
2291
2620
|
}));
|
|
2292
2621
|
try {
|
|
2293
2622
|
try {
|
|
2294
2623
|
// Load the matches
|
|
2295
2624
|
await this.loadMatches({
|
|
2296
|
-
matches,
|
|
2625
|
+
matches: pendingMatches,
|
|
2297
2626
|
checkLatest: () => this.checkLatest(promise),
|
|
2298
2627
|
invalidate: opts?.invalidate
|
|
2299
2628
|
});
|
|
@@ -2308,14 +2637,13 @@
|
|
|
2308
2637
|
}
|
|
2309
2638
|
const exitingMatchIds = previousMatches.filter(id => !this.pendingMatches.includes(id));
|
|
2310
2639
|
const enteringMatchIds = this.pendingMatches.filter(id => !previousMatches.includes(id));
|
|
2311
|
-
const stayingMatchIds = previousMatches.filter(id => this.pendingMatches.includes(id))
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
// }))
|
|
2640
|
+
const stayingMatchIds = previousMatches.filter(id => this.pendingMatches.includes(id));
|
|
2641
|
+
this.__store.setState(s => ({
|
|
2642
|
+
...s,
|
|
2643
|
+
isLoading: false,
|
|
2644
|
+
matches: pendingMatches,
|
|
2645
|
+
pendingMatches: undefined
|
|
2646
|
+
}))
|
|
2319
2647
|
|
|
2320
2648
|
//
|
|
2321
2649
|
;
|
|
@@ -2470,9 +2798,6 @@
|
|
|
2470
2798
|
return false;
|
|
2471
2799
|
}
|
|
2472
2800
|
const baseLocation = opts?.pending ? this.latestLocation : this.state.resolvedLocation;
|
|
2473
|
-
|
|
2474
|
-
// const baseLocation = state.resolvedLocation
|
|
2475
|
-
|
|
2476
2801
|
if (!baseLocation) {
|
|
2477
2802
|
return false;
|
|
2478
2803
|
}
|
|
@@ -2544,7 +2869,7 @@
|
|
|
2544
2869
|
}
|
|
2545
2870
|
return match;
|
|
2546
2871
|
});
|
|
2547
|
-
this.setState(s => {
|
|
2872
|
+
this.__store.setState(s => {
|
|
2548
2873
|
return {
|
|
2549
2874
|
...s,
|
|
2550
2875
|
matches: matches
|
|
@@ -2575,6 +2900,8 @@
|
|
|
2575
2900
|
class PathParamError extends Error {}
|
|
2576
2901
|
function getInitialRouterState(location) {
|
|
2577
2902
|
return {
|
|
2903
|
+
isLoading: false,
|
|
2904
|
+
isTransitioning: false,
|
|
2578
2905
|
status: 'idle',
|
|
2579
2906
|
resolvedLocation: location,
|
|
2580
2907
|
location,
|
|
@@ -2882,6 +3209,7 @@
|
|
|
2882
3209
|
exports.useParams = useParams;
|
|
2883
3210
|
exports.useRouteContext = useRouteContext;
|
|
2884
3211
|
exports.useRouter = useRouter;
|
|
3212
|
+
exports.useRouterState = useRouterState;
|
|
2885
3213
|
exports.useScrollRestoration = useScrollRestoration;
|
|
2886
3214
|
exports.useSearch = useSearch;
|
|
2887
3215
|
exports.useStableCallback = useStableCallback;
|