@tanstack/react-router 0.0.1-beta.235 → 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 +34 -19
- package/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +31 -26
- 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 +144 -94
- 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 +412 -97
- 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 +72 -37
- package/src/RouterProvider.tsx +42 -31
- 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
|
};
|
|
@@ -914,12 +1199,13 @@
|
|
|
914
1199
|
//
|
|
915
1200
|
|
|
916
1201
|
function Matches() {
|
|
917
|
-
const router = useRouter();
|
|
918
1202
|
const {
|
|
919
|
-
|
|
920
|
-
} =
|
|
921
|
-
const
|
|
922
|
-
const
|
|
1203
|
+
routesById
|
|
1204
|
+
} = useRouter();
|
|
1205
|
+
const routerState = useRouterState();
|
|
1206
|
+
const matches = routerState.pendingMatches?.some(d => d.showPending) ? routerState.pendingMatches : routerState.matches;
|
|
1207
|
+
const locationKey = useRouterState().location.state.key;
|
|
1208
|
+
const route = routesById[rootRouteId];
|
|
923
1209
|
const errorComponent = React__namespace.useCallback(props => {
|
|
924
1210
|
return /*#__PURE__*/React__namespace.createElement(ErrorComponent, {
|
|
925
1211
|
...props,
|
|
@@ -1059,31 +1345,45 @@
|
|
|
1059
1345
|
return !!params ? props.children : null;
|
|
1060
1346
|
}
|
|
1061
1347
|
function useMatch(opts) {
|
|
1062
|
-
const router = useRouter();
|
|
1063
1348
|
const nearestMatch = React__namespace.useContext(matchesContext)[0];
|
|
1064
1349
|
const nearestMatchRouteId = nearestMatch?.routeId;
|
|
1065
|
-
const matchRouteId = (
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1350
|
+
const matchRouteId = useRouterState({
|
|
1351
|
+
select: state => {
|
|
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);
|
|
1354
|
+
return match.routeId;
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1069
1357
|
if (opts?.strict ?? true) {
|
|
1070
1358
|
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
1359
|
}
|
|
1072
|
-
const matchSelection = (
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1360
|
+
const matchSelection = useRouterState({
|
|
1361
|
+
select: state => {
|
|
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);
|
|
1364
|
+
invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
|
|
1365
|
+
return opts?.select ? opts.select(match) : match;
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1077
1368
|
return matchSelection;
|
|
1078
1369
|
}
|
|
1079
1370
|
const matchesContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
1080
|
-
function useMatches() {
|
|
1081
|
-
const router = useRouter();
|
|
1371
|
+
function useMatches(opts) {
|
|
1082
1372
|
const contextMatches = React__namespace.useContext(matchesContext);
|
|
1083
|
-
return
|
|
1373
|
+
return useRouterState({
|
|
1374
|
+
select: state => {
|
|
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));
|
|
1377
|
+
return opts?.select ? opts.select(matches) : matches;
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1084
1380
|
}
|
|
1085
1381
|
function useLoaderData(opts) {
|
|
1086
|
-
|
|
1382
|
+
const match = useMatch({
|
|
1383
|
+
...opts,
|
|
1384
|
+
select: undefined
|
|
1385
|
+
});
|
|
1386
|
+
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
1087
1387
|
}
|
|
1088
1388
|
|
|
1089
1389
|
const routerContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
@@ -1114,31 +1414,29 @@
|
|
|
1114
1414
|
function RouterProviderInner({
|
|
1115
1415
|
router
|
|
1116
1416
|
}) {
|
|
1117
|
-
const [preState, setState] = React__namespace.useState(() => router.state);
|
|
1118
1417
|
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
1418
|
router.startReactTransition = startReactTransition;
|
|
1419
|
+
React__namespace.useEffect(() => {
|
|
1420
|
+
if (isTransitioning) {
|
|
1421
|
+
router.__store.setState(s => ({
|
|
1422
|
+
...s,
|
|
1423
|
+
isTransitioning
|
|
1424
|
+
}));
|
|
1425
|
+
}
|
|
1426
|
+
}, [isTransitioning]);
|
|
1129
1427
|
const tryLoad = () => {
|
|
1130
|
-
startReactTransition(() => {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
})
|
|
1428
|
+
// startReactTransition(() => {
|
|
1429
|
+
try {
|
|
1430
|
+
router.load();
|
|
1431
|
+
} catch (err) {
|
|
1432
|
+
console.error(err);
|
|
1433
|
+
}
|
|
1434
|
+
// })
|
|
1137
1435
|
};
|
|
1138
1436
|
useLayoutEffect$1(() => {
|
|
1139
1437
|
const unsub = router.history.subscribe(() => {
|
|
1140
1438
|
router.latestLocation = router.parseLocation(router.latestLocation);
|
|
1141
|
-
if (state.location !== router.latestLocation) {
|
|
1439
|
+
if (router.state.location !== router.latestLocation) {
|
|
1142
1440
|
tryLoad();
|
|
1143
1441
|
}
|
|
1144
1442
|
});
|
|
@@ -1148,7 +1446,7 @@
|
|
|
1148
1446
|
hash: true,
|
|
1149
1447
|
state: true
|
|
1150
1448
|
});
|
|
1151
|
-
if (state.location.href !== nextLocation.href) {
|
|
1449
|
+
if (router.state.location.href !== nextLocation.href) {
|
|
1152
1450
|
router.commitLocation({
|
|
1153
1451
|
...nextLocation,
|
|
1154
1452
|
replace: true
|
|
@@ -1159,20 +1457,21 @@
|
|
|
1159
1457
|
};
|
|
1160
1458
|
}, [router.history]);
|
|
1161
1459
|
useLayoutEffect$1(() => {
|
|
1162
|
-
if (!isTransitioning && state.resolvedLocation !== state.location) {
|
|
1460
|
+
if (!isTransitioning && router.state.resolvedLocation !== router.state.location) {
|
|
1163
1461
|
router.emit({
|
|
1164
1462
|
type: 'onResolved',
|
|
1165
|
-
fromLocation: state.resolvedLocation,
|
|
1166
|
-
toLocation: state.location,
|
|
1167
|
-
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
|
|
1168
1466
|
});
|
|
1169
1467
|
router.pendingMatches = [];
|
|
1170
|
-
setState(s => ({
|
|
1468
|
+
router.__store.setState(s => ({
|
|
1171
1469
|
...s,
|
|
1470
|
+
isTransitioning: false,
|
|
1172
1471
|
resolvedLocation: s.location
|
|
1173
1472
|
}));
|
|
1174
1473
|
}
|
|
1175
|
-
});
|
|
1474
|
+
}, [isTransitioning]);
|
|
1176
1475
|
useLayoutEffect$1(() => {
|
|
1177
1476
|
if (!window.__TSR_DEHYDRATED__) {
|
|
1178
1477
|
tryLoad();
|
|
@@ -1183,7 +1482,11 @@
|
|
|
1183
1482
|
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
1184
1483
|
}
|
|
1185
1484
|
function getRouteMatch(state, id) {
|
|
1186
|
-
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
1485
|
+
return [...(state.pendingMatches ?? []), ...state.matches].find(d => d.id === id);
|
|
1486
|
+
}
|
|
1487
|
+
function useRouterState(opts) {
|
|
1488
|
+
const router = useRouter();
|
|
1489
|
+
return useStore(router.__store, opts?.select);
|
|
1187
1490
|
}
|
|
1188
1491
|
function useRouter() {
|
|
1189
1492
|
const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || routerContext : routerContext;
|
|
@@ -1546,9 +1849,6 @@
|
|
|
1546
1849
|
// by the router provider once rendered. We provide these so that the
|
|
1547
1850
|
// router can be used in a non-react environment if necessary
|
|
1548
1851
|
startReactTransition = fn => fn();
|
|
1549
|
-
setState = updater => {
|
|
1550
|
-
this.state = functionalUpdate(updater, this.state);
|
|
1551
|
-
};
|
|
1552
1852
|
update = newOptions => {
|
|
1553
1853
|
this.options = {
|
|
1554
1854
|
...this.options,
|
|
@@ -1563,10 +1863,20 @@
|
|
|
1563
1863
|
this.routeTree = this.options.routeTree;
|
|
1564
1864
|
this.buildRouteTree();
|
|
1565
1865
|
}
|
|
1566
|
-
if (!this.
|
|
1567
|
-
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
|
+
});
|
|
1568
1875
|
}
|
|
1569
1876
|
};
|
|
1877
|
+
get state() {
|
|
1878
|
+
return this.__store.state;
|
|
1879
|
+
}
|
|
1570
1880
|
buildRouteTree = () => {
|
|
1571
1881
|
this.routesById = {};
|
|
1572
1882
|
this.routesByPath = {};
|
|
@@ -1838,7 +2148,7 @@
|
|
|
1838
2148
|
getRouteMatch(this.state, id)?.abortController?.abort();
|
|
1839
2149
|
};
|
|
1840
2150
|
cancelMatches = () => {
|
|
1841
|
-
this.state.
|
|
2151
|
+
this.state.pendingMatches?.forEach(match => {
|
|
1842
2152
|
this.cancelMatch(match.id);
|
|
1843
2153
|
});
|
|
1844
2154
|
};
|
|
@@ -2029,6 +2339,12 @@
|
|
|
2029
2339
|
}) => {
|
|
2030
2340
|
let latestPromise;
|
|
2031
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
|
+
};
|
|
2032
2348
|
|
|
2033
2349
|
// Check each match middleware to see if the route can be accessed
|
|
2034
2350
|
try {
|
|
@@ -2185,12 +2501,10 @@
|
|
|
2185
2501
|
loadPromise
|
|
2186
2502
|
};
|
|
2187
2503
|
if (!preload) {
|
|
2188
|
-
|
|
2189
|
-
...s,
|
|
2190
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2191
|
-
}));
|
|
2504
|
+
updatePendingMatch(match);
|
|
2192
2505
|
}
|
|
2193
2506
|
let didShowPending = false;
|
|
2507
|
+
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2194
2508
|
await new Promise(async resolve => {
|
|
2195
2509
|
// If the route has a pending component and a pendingMs option,
|
|
2196
2510
|
// forcefully show the pending component
|
|
@@ -2202,17 +2516,13 @@
|
|
|
2202
2516
|
...match,
|
|
2203
2517
|
showPending: true
|
|
2204
2518
|
};
|
|
2205
|
-
|
|
2206
|
-
...s,
|
|
2207
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2208
|
-
}));
|
|
2519
|
+
updatePendingMatch(match);
|
|
2209
2520
|
resolve();
|
|
2210
2521
|
});
|
|
2211
2522
|
}
|
|
2212
2523
|
try {
|
|
2213
2524
|
const loaderData = await loadPromise;
|
|
2214
2525
|
if (latestPromise = checkLatest()) return await latestPromise;
|
|
2215
|
-
const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
|
|
2216
2526
|
if (didShowPending && pendingMinMs) {
|
|
2217
2527
|
await new Promise(r => setTimeout(r, pendingMinMs));
|
|
2218
2528
|
}
|
|
@@ -2242,12 +2552,19 @@
|
|
|
2242
2552
|
isFetching: false,
|
|
2243
2553
|
updatedAt: Date.now()
|
|
2244
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
|
+
}
|
|
2245
2565
|
}
|
|
2246
2566
|
if (!preload) {
|
|
2247
|
-
|
|
2248
|
-
...s,
|
|
2249
|
-
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2250
|
-
}));
|
|
2567
|
+
updatePendingMatch(match);
|
|
2251
2568
|
}
|
|
2252
2569
|
resolve();
|
|
2253
2570
|
});
|
|
@@ -2276,24 +2593,23 @@
|
|
|
2276
2593
|
});
|
|
2277
2594
|
|
|
2278
2595
|
// Match the routes
|
|
2279
|
-
let
|
|
2596
|
+
let pendingMatches = this.matchRoutes(next.pathname, next.search, {
|
|
2280
2597
|
debug: true
|
|
2281
2598
|
});
|
|
2282
|
-
this.pendingMatches = matches;
|
|
2283
2599
|
const previousMatches = this.state.matches;
|
|
2284
2600
|
|
|
2285
2601
|
// Ingest the new matches
|
|
2286
|
-
this.setState(s => ({
|
|
2602
|
+
this.__store.setState(s => ({
|
|
2287
2603
|
...s,
|
|
2288
|
-
|
|
2604
|
+
isLoading: true,
|
|
2289
2605
|
location: next,
|
|
2290
|
-
|
|
2606
|
+
pendingMatches
|
|
2291
2607
|
}));
|
|
2292
2608
|
try {
|
|
2293
2609
|
try {
|
|
2294
2610
|
// Load the matches
|
|
2295
2611
|
await this.loadMatches({
|
|
2296
|
-
matches,
|
|
2612
|
+
matches: pendingMatches,
|
|
2297
2613
|
checkLatest: () => this.checkLatest(promise),
|
|
2298
2614
|
invalidate: opts?.invalidate
|
|
2299
2615
|
});
|
|
@@ -2308,14 +2624,13 @@
|
|
|
2308
2624
|
}
|
|
2309
2625
|
const exitingMatchIds = previousMatches.filter(id => !this.pendingMatches.includes(id));
|
|
2310
2626
|
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
|
-
// }))
|
|
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
|
+
}))
|
|
2319
2634
|
|
|
2320
2635
|
//
|
|
2321
2636
|
;
|
|
@@ -2470,9 +2785,6 @@
|
|
|
2470
2785
|
return false;
|
|
2471
2786
|
}
|
|
2472
2787
|
const baseLocation = opts?.pending ? this.latestLocation : this.state.resolvedLocation;
|
|
2473
|
-
|
|
2474
|
-
// const baseLocation = state.resolvedLocation
|
|
2475
|
-
|
|
2476
2788
|
if (!baseLocation) {
|
|
2477
2789
|
return false;
|
|
2478
2790
|
}
|
|
@@ -2544,7 +2856,7 @@
|
|
|
2544
2856
|
}
|
|
2545
2857
|
return match;
|
|
2546
2858
|
});
|
|
2547
|
-
this.setState(s => {
|
|
2859
|
+
this.__store.setState(s => {
|
|
2548
2860
|
return {
|
|
2549
2861
|
...s,
|
|
2550
2862
|
matches: matches
|
|
@@ -2575,6 +2887,8 @@
|
|
|
2575
2887
|
class PathParamError extends Error {}
|
|
2576
2888
|
function getInitialRouterState(location) {
|
|
2577
2889
|
return {
|
|
2890
|
+
isLoading: false,
|
|
2891
|
+
isTransitioning: false,
|
|
2578
2892
|
status: 'idle',
|
|
2579
2893
|
resolvedLocation: location,
|
|
2580
2894
|
location,
|
|
@@ -2882,6 +3196,7 @@
|
|
|
2882
3196
|
exports.useParams = useParams;
|
|
2883
3197
|
exports.useRouteContext = useRouteContext;
|
|
2884
3198
|
exports.useRouter = useRouter;
|
|
3199
|
+
exports.useRouterState = useRouterState;
|
|
2885
3200
|
exports.useScrollRestoration = useScrollRestoration;
|
|
2886
3201
|
exports.useSearch = useSearch;
|
|
2887
3202
|
exports.useStableCallback = useStableCallback;
|