@tanstack/react-router 0.0.1-beta.22 → 0.0.1-beta.220
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/LICENSE +21 -0
- package/build/cjs/CatchBoundary.js +126 -0
- package/build/cjs/CatchBoundary.js.map +1 -0
- package/build/cjs/Matches.js +235 -0
- package/build/cjs/Matches.js.map +1 -0
- package/build/cjs/RouterProvider.js +1085 -0
- package/build/cjs/RouterProvider.js.map +1 -0
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +1 -19
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
- package/build/cjs/awaited.js +45 -0
- package/build/cjs/awaited.js.map +1 -0
- package/build/cjs/defer.js +39 -0
- package/build/cjs/defer.js.map +1 -0
- package/build/cjs/fileRoute.js +29 -0
- package/build/cjs/fileRoute.js.map +1 -0
- package/build/cjs/index.js +135 -0
- package/build/cjs/index.js.map +1 -0
- package/build/cjs/lazyRouteComponent.js +57 -0
- package/build/cjs/lazyRouteComponent.js.map +1 -0
- package/build/cjs/link.js +151 -0
- package/build/cjs/link.js.map +1 -0
- package/build/cjs/path.js +211 -0
- package/build/cjs/path.js.map +1 -0
- package/build/cjs/qss.js +65 -0
- package/build/cjs/qss.js.map +1 -0
- package/build/cjs/redirects.js +27 -0
- package/build/cjs/redirects.js.map +1 -0
- package/build/cjs/route.js +139 -0
- package/build/cjs/route.js.map +1 -0
- package/build/cjs/router.js +160 -0
- package/build/cjs/router.js.map +1 -0
- package/build/cjs/scroll-restoration.js +186 -0
- package/build/cjs/scroll-restoration.js.map +1 -0
- package/build/cjs/searchParams.js +83 -0
- package/build/cjs/searchParams.js.map +1 -0
- package/build/cjs/useBlocker.js +64 -0
- package/build/cjs/useBlocker.js.map +1 -0
- package/build/cjs/useNavigate.js +78 -0
- package/build/cjs/useNavigate.js.map +1 -0
- package/build/cjs/useParams.js +28 -0
- package/build/cjs/useParams.js.map +1 -0
- package/build/cjs/useSearch.js +27 -0
- package/build/cjs/useSearch.js.map +1 -0
- package/build/cjs/utils.js +236 -0
- package/build/cjs/utils.js.map +1 -0
- package/build/esm/index.js +2136 -2564
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +59 -49
- package/build/stats-react.json +922 -43
- package/build/types/CatchBoundary.d.ts +33 -0
- package/build/types/Matches.d.ts +34 -0
- package/build/types/RouterProvider.d.ts +87 -0
- package/build/types/awaited.d.ts +8 -0
- package/build/types/defer.d.ts +19 -0
- package/build/types/fileRoute.d.ts +32 -0
- package/build/types/history.d.ts +7 -0
- package/build/types/index.d.ts +27 -104
- package/build/types/injectHtml.d.ts +0 -0
- package/build/types/lazyRouteComponent.d.ts +2 -0
- package/build/types/link.d.ts +105 -0
- package/build/types/location.d.ts +14 -0
- package/build/types/path.d.ts +16 -0
- package/build/types/qss.d.ts +2 -0
- package/build/types/redirects.d.ts +10 -0
- package/build/types/route.d.ts +270 -0
- package/build/types/routeInfo.d.ts +22 -0
- package/build/types/router.d.ts +123 -0
- package/build/types/scroll-restoration.d.ts +6 -0
- package/build/types/searchParams.d.ts +7 -0
- package/build/types/useBlocker.d.ts +8 -0
- package/build/types/useNavigate.d.ts +20 -0
- package/build/types/useParams.d.ts +7 -0
- package/build/types/useSearch.d.ts +7 -0
- package/build/types/utils.d.ts +66 -0
- package/build/umd/index.development.js +2399 -2484
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +4 -4
- package/build/umd/index.production.js.map +1 -1
- package/package.json +9 -10
- package/src/CatchBoundary.tsx +98 -0
- package/src/Matches.tsx +345 -0
- package/src/RouterProvider.tsx +1575 -0
- package/src/awaited.tsx +40 -0
- package/src/defer.ts +55 -0
- package/src/fileRoute.ts +153 -0
- package/src/history.ts +8 -0
- package/src/index.tsx +28 -693
- package/src/injectHtml.ts +28 -0
- package/src/lazyRouteComponent.tsx +33 -0
- package/src/link.tsx +508 -0
- package/src/location.ts +15 -0
- package/src/path.ts +256 -0
- package/src/qss.ts +53 -0
- package/src/redirects.ts +31 -0
- package/src/route.ts +837 -0
- package/src/routeInfo.ts +68 -0
- package/src/router.ts +330 -0
- package/src/scroll-restoration.tsx +192 -0
- package/src/searchParams.ts +79 -0
- package/src/useBlocker.tsx +34 -0
- package/src/useNavigate.tsx +109 -0
- package/src/useParams.tsx +25 -0
- package/src/useSearch.tsx +25 -0
- package/src/utils.ts +350 -0
- package/build/cjs/react-router/src/index.js +0 -466
- package/build/cjs/react-router/src/index.js.map +0 -1
- package/build/cjs/router-core/build/esm/index.js +0 -2523
- package/build/cjs/router-core/build/esm/index.js.map +0 -1
package/build/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router
|
|
2
|
+
* @tanstack/react-router/src/index.tsx
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) TanStack
|
|
5
5
|
*
|
|
@@ -8,978 +8,284 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
+
import { createBrowserHistory } from '@tanstack/history';
|
|
12
|
+
export * from '@tanstack/history';
|
|
13
|
+
import invariant from 'tiny-invariant';
|
|
14
|
+
export { default as invariant } from 'tiny-invariant';
|
|
15
|
+
import warning from 'tiny-warning';
|
|
16
|
+
export { default as warning } from 'tiny-warning';
|
|
11
17
|
import * as React from 'react';
|
|
12
|
-
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
13
18
|
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
function CatchBoundary(props) {
|
|
20
|
+
const errorComponent = props.errorComponent ?? ErrorComponent;
|
|
21
|
+
return /*#__PURE__*/React.createElement(CatchBoundaryImpl, {
|
|
22
|
+
resetKey: props.resetKey,
|
|
23
|
+
onCatch: props.onCatch,
|
|
24
|
+
children: ({
|
|
25
|
+
error
|
|
26
|
+
}) => {
|
|
27
|
+
if (error) {
|
|
28
|
+
return /*#__PURE__*/React.createElement(errorComponent, {
|
|
29
|
+
error
|
|
30
|
+
});
|
|
23
31
|
}
|
|
32
|
+
return props.children;
|
|
24
33
|
}
|
|
25
|
-
|
|
26
|
-
return target;
|
|
27
|
-
};
|
|
28
|
-
return _extends$2.apply(this, arguments);
|
|
34
|
+
});
|
|
29
35
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
key = sourceKeys[i];
|
|
39
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
40
|
-
target[key] = source[key];
|
|
36
|
+
class CatchBoundaryImpl extends React.Component {
|
|
37
|
+
state = {
|
|
38
|
+
error: null
|
|
39
|
+
};
|
|
40
|
+
static getDerivedStateFromError(error) {
|
|
41
|
+
return {
|
|
42
|
+
error
|
|
43
|
+
};
|
|
41
44
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
* router-core
|
|
48
|
-
*
|
|
49
|
-
* Copyright (c) TanStack
|
|
50
|
-
*
|
|
51
|
-
* This source code is licensed under the MIT license found in the
|
|
52
|
-
* LICENSE.md file in the root directory of this source tree.
|
|
53
|
-
*
|
|
54
|
-
* @license MIT
|
|
55
|
-
*/
|
|
56
|
-
function _extends$1() {
|
|
57
|
-
_extends$1 = Object.assign ? Object.assign.bind() : function (target) {
|
|
58
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
59
|
-
var source = arguments[i];
|
|
60
|
-
|
|
61
|
-
for (var key in source) {
|
|
62
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
63
|
-
target[key] = source[key];
|
|
64
|
-
}
|
|
65
|
-
}
|
|
45
|
+
componentDidUpdate(prevProps, prevState) {
|
|
46
|
+
if (prevState.error && prevProps.resetKey !== this.props.resetKey) {
|
|
47
|
+
this.setState({
|
|
48
|
+
error: null
|
|
49
|
+
});
|
|
66
50
|
}
|
|
67
|
-
|
|
68
|
-
return target;
|
|
69
|
-
};
|
|
70
|
-
return _extends$1.apply(this, arguments);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Actions represent the type of change to a location value.
|
|
75
|
-
*
|
|
76
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#action
|
|
77
|
-
*/
|
|
78
|
-
var Action;
|
|
79
|
-
|
|
80
|
-
(function (Action) {
|
|
81
|
-
/**
|
|
82
|
-
* A POP indicates a change to an arbitrary index in the history stack, such
|
|
83
|
-
* as a back or forward navigation. It does not describe the direction of the
|
|
84
|
-
* navigation, only that the current index changed.
|
|
85
|
-
*
|
|
86
|
-
* Note: This is the default action for newly created history objects.
|
|
87
|
-
*/
|
|
88
|
-
Action["Pop"] = "POP";
|
|
89
|
-
/**
|
|
90
|
-
* A PUSH indicates a new entry being added to the history stack, such as when
|
|
91
|
-
* a link is clicked and a new page loads. When this happens, all subsequent
|
|
92
|
-
* entries in the stack are lost.
|
|
93
|
-
*/
|
|
94
|
-
|
|
95
|
-
Action["Push"] = "PUSH";
|
|
96
|
-
/**
|
|
97
|
-
* A REPLACE indicates the entry at the current index in the history stack
|
|
98
|
-
* being replaced by a new one.
|
|
99
|
-
*/
|
|
100
|
-
|
|
101
|
-
Action["Replace"] = "REPLACE";
|
|
102
|
-
})(Action || (Action = {}));
|
|
103
|
-
|
|
104
|
-
var readOnly = process.env.NODE_ENV !== "production" ? function (obj) {
|
|
105
|
-
return Object.freeze(obj);
|
|
106
|
-
} : function (obj) {
|
|
107
|
-
return obj;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
function warning$1(cond, message) {
|
|
111
|
-
if (!cond) {
|
|
112
|
-
// eslint-disable-next-line no-console
|
|
113
|
-
if (typeof console !== 'undefined') console.warn(message);
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
// Welcome to debugging history!
|
|
117
|
-
//
|
|
118
|
-
// This error is thrown as a convenience so you can more easily
|
|
119
|
-
// find the source for a warning that appears in the console by
|
|
120
|
-
// enabling "pause on exceptions" in your JavaScript debugger.
|
|
121
|
-
throw new Error(message); // eslint-disable-next-line no-empty
|
|
122
|
-
} catch (e) {}
|
|
123
51
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
var HashChangeEventType = 'hashchange';
|
|
128
|
-
var PopStateEventType = 'popstate';
|
|
129
|
-
/**
|
|
130
|
-
* Browser history stores the location in regular URLs. This is the standard for
|
|
131
|
-
* most web apps, but it requires some configuration on the server to ensure you
|
|
132
|
-
* serve the same app at multiple URLs.
|
|
133
|
-
*
|
|
134
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory
|
|
135
|
-
*/
|
|
136
|
-
|
|
137
|
-
function createBrowserHistory(options) {
|
|
138
|
-
if (options === void 0) {
|
|
139
|
-
options = {};
|
|
52
|
+
componentDidCatch(error) {
|
|
53
|
+
console.error(error);
|
|
54
|
+
this.props.onCatch?.(error);
|
|
140
55
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
_options$window = _options.window,
|
|
144
|
-
window = _options$window === void 0 ? document.defaultView : _options$window;
|
|
145
|
-
var globalHistory = window.history;
|
|
146
|
-
|
|
147
|
-
function getIndexAndLocation() {
|
|
148
|
-
var _window$location = window.location,
|
|
149
|
-
pathname = _window$location.pathname,
|
|
150
|
-
search = _window$location.search,
|
|
151
|
-
hash = _window$location.hash;
|
|
152
|
-
var state = globalHistory.state || {};
|
|
153
|
-
return [state.idx, readOnly({
|
|
154
|
-
pathname: pathname,
|
|
155
|
-
search: search,
|
|
156
|
-
hash: hash,
|
|
157
|
-
state: state.usr || null,
|
|
158
|
-
key: state.key || 'default'
|
|
159
|
-
})];
|
|
56
|
+
render() {
|
|
57
|
+
return this.props.children(this.state);
|
|
160
58
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
var _getIndexAndLocation = getIndexAndLocation(),
|
|
172
|
-
nextIndex = _getIndexAndLocation[0],
|
|
173
|
-
nextLocation = _getIndexAndLocation[1];
|
|
174
|
-
|
|
175
|
-
if (blockers.length) {
|
|
176
|
-
if (nextIndex != null) {
|
|
177
|
-
var delta = index - nextIndex;
|
|
178
|
-
|
|
179
|
-
if (delta) {
|
|
180
|
-
// Revert the POP
|
|
181
|
-
blockedPopTx = {
|
|
182
|
-
action: nextAction,
|
|
183
|
-
location: nextLocation,
|
|
184
|
-
retry: function retry() {
|
|
185
|
-
go(delta * -1);
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
go(delta);
|
|
189
|
-
}
|
|
190
|
-
} else {
|
|
191
|
-
// Trying to POP to a location with no index. We did not create
|
|
192
|
-
// this location, so we can't effectively block the navigation.
|
|
193
|
-
process.env.NODE_ENV !== "production" ? warning$1(false, // TODO: Write up a doc that explains our blocking strategy in
|
|
194
|
-
// detail and link to it here so people can understand better what
|
|
195
|
-
// is going on and how to avoid it.
|
|
196
|
-
"You are trying to block a POP navigation to a location that was not " + "created by the history library. The block will fail silently in " + "production, but in general you should do all navigation with the " + "history library (instead of using window.history.pushState directly) " + "to avoid this situation.") : void 0;
|
|
197
|
-
}
|
|
198
|
-
} else {
|
|
199
|
-
applyTx(nextAction);
|
|
200
|
-
}
|
|
59
|
+
}
|
|
60
|
+
function ErrorComponent({
|
|
61
|
+
error
|
|
62
|
+
}) {
|
|
63
|
+
const [show, setShow] = React.useState(process.env.NODE_ENV !== 'production');
|
|
64
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
65
|
+
style: {
|
|
66
|
+
padding: '.5rem',
|
|
67
|
+
maxWidth: '100%'
|
|
201
68
|
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
var _getIndexAndLocation2 = getIndexAndLocation(),
|
|
208
|
-
index = _getIndexAndLocation2[0],
|
|
209
|
-
location = _getIndexAndLocation2[1];
|
|
210
|
-
|
|
211
|
-
var listeners = createEvents();
|
|
212
|
-
var blockers = createEvents();
|
|
213
|
-
|
|
214
|
-
if (index == null) {
|
|
215
|
-
index = 0;
|
|
216
|
-
globalHistory.replaceState(_extends$1({}, globalHistory.state, {
|
|
217
|
-
idx: index
|
|
218
|
-
}), '');
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
function createHref(to) {
|
|
222
|
-
return typeof to === 'string' ? to : createPath(to);
|
|
223
|
-
} // state defaults to `null` because `window.history.state` does
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
function getNextLocation(to, state) {
|
|
227
|
-
if (state === void 0) {
|
|
228
|
-
state = null;
|
|
69
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
70
|
+
style: {
|
|
71
|
+
display: 'flex',
|
|
72
|
+
alignItems: 'center',
|
|
73
|
+
gap: '.5rem'
|
|
229
74
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
hash: '',
|
|
234
|
-
search: ''
|
|
235
|
-
}, typeof to === 'string' ? parsePath(to) : to, {
|
|
236
|
-
state: state,
|
|
237
|
-
key: createKey()
|
|
238
|
-
}));
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function getHistoryStateAndUrl(nextLocation, index) {
|
|
242
|
-
return [{
|
|
243
|
-
usr: nextLocation.state,
|
|
244
|
-
key: nextLocation.key,
|
|
245
|
-
idx: index
|
|
246
|
-
}, createHref(nextLocation)];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function allowTx(action, location, retry) {
|
|
250
|
-
return !blockers.length || (blockers.call({
|
|
251
|
-
action: action,
|
|
252
|
-
location: location,
|
|
253
|
-
retry: retry
|
|
254
|
-
}), false);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
function applyTx(nextAction) {
|
|
258
|
-
action = nextAction;
|
|
259
|
-
|
|
260
|
-
var _getIndexAndLocation3 = getIndexAndLocation();
|
|
261
|
-
|
|
262
|
-
index = _getIndexAndLocation3[0];
|
|
263
|
-
location = _getIndexAndLocation3[1];
|
|
264
|
-
listeners.call({
|
|
265
|
-
action: action,
|
|
266
|
-
location: location
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function push(to, state) {
|
|
271
|
-
var nextAction = Action.Push;
|
|
272
|
-
var nextLocation = getNextLocation(to, state);
|
|
273
|
-
|
|
274
|
-
function retry() {
|
|
275
|
-
push(to, state);
|
|
75
|
+
}, /*#__PURE__*/React.createElement("strong", {
|
|
76
|
+
style: {
|
|
77
|
+
fontSize: '1rem'
|
|
276
78
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
window.location.assign(url);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
applyTx(nextAction);
|
|
79
|
+
}, "Something went wrong!"), /*#__PURE__*/React.createElement("button", {
|
|
80
|
+
style: {
|
|
81
|
+
appearance: 'none',
|
|
82
|
+
fontSize: '.6em',
|
|
83
|
+
border: '1px solid currentColor',
|
|
84
|
+
padding: '.1rem .2rem',
|
|
85
|
+
fontWeight: 'bold',
|
|
86
|
+
borderRadius: '.25rem'
|
|
87
|
+
},
|
|
88
|
+
onClick: () => setShow(d => !d)
|
|
89
|
+
}, show ? 'Hide Error' : 'Show Error')), /*#__PURE__*/React.createElement("div", {
|
|
90
|
+
style: {
|
|
91
|
+
height: '.25rem'
|
|
294
92
|
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
93
|
+
}), show ? /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("pre", {
|
|
94
|
+
style: {
|
|
95
|
+
fontSize: '.7em',
|
|
96
|
+
border: '1px solid red',
|
|
97
|
+
borderRadius: '.25rem',
|
|
98
|
+
padding: '.3rem',
|
|
99
|
+
color: 'red',
|
|
100
|
+
overflow: 'auto'
|
|
303
101
|
}
|
|
102
|
+
}, error.message ? /*#__PURE__*/React.createElement("code", null, error.message) : null)) : null);
|
|
103
|
+
}
|
|
304
104
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
105
|
+
// export type Expand<T> = T
|
|
106
|
+
|
|
107
|
+
// type Compute<T> = { [K in keyof T]: T[K] } | never
|
|
108
|
+
|
|
109
|
+
// type AllKeys<T> = T extends any ? keyof T : never
|
|
110
|
+
|
|
111
|
+
// export type MergeUnion<T, Keys extends keyof T = keyof T> = Compute<
|
|
112
|
+
// {
|
|
113
|
+
// [K in Keys]: T[Keys]
|
|
114
|
+
// } & {
|
|
115
|
+
// [K in AllKeys<T>]?: T extends any
|
|
116
|
+
// ? K extends keyof T
|
|
117
|
+
// ? T[K]
|
|
118
|
+
// : never
|
|
119
|
+
// : never
|
|
120
|
+
// }
|
|
121
|
+
// >
|
|
122
|
+
// // Sample types to merge
|
|
123
|
+
// type TypeA = {
|
|
124
|
+
// shared: string
|
|
125
|
+
// onlyInA: string
|
|
126
|
+
// nested: {
|
|
127
|
+
// shared: string
|
|
128
|
+
// aProp: string
|
|
129
|
+
// }
|
|
130
|
+
// array: string[]
|
|
131
|
+
// }
|
|
132
|
+
// type TypeB = {
|
|
133
|
+
// shared: number
|
|
134
|
+
// onlyInB: number
|
|
135
|
+
// nested: {
|
|
136
|
+
// shared: number
|
|
137
|
+
// bProp: number
|
|
138
|
+
// }
|
|
139
|
+
// array: number[]
|
|
140
|
+
// }
|
|
141
|
+
// type TypeC = {
|
|
142
|
+
// shared: boolean
|
|
143
|
+
// onlyInC: boolean
|
|
144
|
+
// nested: {
|
|
145
|
+
// shared: boolean
|
|
146
|
+
// cProp: boolean
|
|
147
|
+
// }
|
|
148
|
+
// array: boolean[]
|
|
149
|
+
// }
|
|
150
|
+
// type Test = Expand<Assign<TypeA, TypeB>>
|
|
151
|
+
// // Using DeepMerge to merge TypeA and TypeB
|
|
152
|
+
// type MergedType = Expand<AssignAll<[TypeA, TypeB, TypeC]>>
|
|
153
|
+
//
|
|
310
154
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
155
|
+
const isServer = typeof document === 'undefined';
|
|
156
|
+
function last(arr) {
|
|
157
|
+
return arr[arr.length - 1];
|
|
158
|
+
}
|
|
159
|
+
function isFunction(d) {
|
|
160
|
+
return typeof d === 'function';
|
|
161
|
+
}
|
|
162
|
+
function functionalUpdate(updater, previous) {
|
|
163
|
+
if (isFunction(updater)) {
|
|
164
|
+
return updater(previous);
|
|
314
165
|
}
|
|
166
|
+
return updater;
|
|
167
|
+
}
|
|
168
|
+
function pick(parent, keys) {
|
|
169
|
+
return keys.reduce((obj, key) => {
|
|
170
|
+
obj[key] = parent[key];
|
|
171
|
+
return obj;
|
|
172
|
+
}, {});
|
|
173
|
+
}
|
|
315
174
|
|
|
316
|
-
|
|
317
|
-
|
|
175
|
+
/**
|
|
176
|
+
* This function returns `a` if `b` is deeply equal.
|
|
177
|
+
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
178
|
+
* This can be used for structural sharing between immutable JSON values for example.
|
|
179
|
+
* Do not use this with signals
|
|
180
|
+
*/
|
|
181
|
+
function replaceEqualDeep(prev, _next) {
|
|
182
|
+
if (prev === _next) {
|
|
183
|
+
return prev;
|
|
318
184
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
go: go,
|
|
333
|
-
back: function back() {
|
|
334
|
-
go(-1);
|
|
335
|
-
},
|
|
336
|
-
forward: function forward() {
|
|
337
|
-
go(1);
|
|
338
|
-
},
|
|
339
|
-
listen: function listen(listener) {
|
|
340
|
-
return listeners.push(listener);
|
|
341
|
-
},
|
|
342
|
-
block: function block(blocker) {
|
|
343
|
-
var unblock = blockers.push(blocker);
|
|
344
|
-
|
|
345
|
-
if (blockers.length === 1) {
|
|
346
|
-
window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
185
|
+
const next = _next;
|
|
186
|
+
const array = Array.isArray(prev) && Array.isArray(next);
|
|
187
|
+
if (array || isPlainObject(prev) && isPlainObject(next)) {
|
|
188
|
+
const prevSize = array ? prev.length : Object.keys(prev).length;
|
|
189
|
+
const nextItems = array ? next : Object.keys(next);
|
|
190
|
+
const nextSize = nextItems.length;
|
|
191
|
+
const copy = array ? [] : {};
|
|
192
|
+
let equalItems = 0;
|
|
193
|
+
for (let i = 0; i < nextSize; i++) {
|
|
194
|
+
const key = array ? i : nextItems[i];
|
|
195
|
+
copy[key] = replaceEqualDeep(prev[key], next[key]);
|
|
196
|
+
if (copy[key] === prev[key]) {
|
|
197
|
+
equalItems++;
|
|
347
198
|
}
|
|
348
|
-
|
|
349
|
-
return function () {
|
|
350
|
-
unblock(); // Remove the beforeunload listener so the document may
|
|
351
|
-
// still be salvageable in the pagehide event.
|
|
352
|
-
// See https://html.spec.whatwg.org/#unloading-documents
|
|
353
|
-
|
|
354
|
-
if (!blockers.length) {
|
|
355
|
-
window.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
356
|
-
}
|
|
357
|
-
};
|
|
358
199
|
}
|
|
359
|
-
|
|
360
|
-
return history;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Hash history stores the location in window.location.hash. This makes it ideal
|
|
364
|
-
* for situations where you don't want to send the location to the server for
|
|
365
|
-
* some reason, either because you do cannot configure it or the URL space is
|
|
366
|
-
* reserved for something else.
|
|
367
|
-
*
|
|
368
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory
|
|
369
|
-
*/
|
|
370
|
-
|
|
371
|
-
function createHashHistory(options) {
|
|
372
|
-
if (options === void 0) {
|
|
373
|
-
options = {};
|
|
200
|
+
return prevSize === nextSize && equalItems === prevSize ? prev : copy;
|
|
374
201
|
}
|
|
202
|
+
return next;
|
|
203
|
+
}
|
|
375
204
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
function getIndexAndLocation() {
|
|
382
|
-
var _parsePath = parsePath(window.location.hash.substr(1)),
|
|
383
|
-
_parsePath$pathname = _parsePath.pathname,
|
|
384
|
-
pathname = _parsePath$pathname === void 0 ? '/' : _parsePath$pathname,
|
|
385
|
-
_parsePath$search = _parsePath.search,
|
|
386
|
-
search = _parsePath$search === void 0 ? '' : _parsePath$search,
|
|
387
|
-
_parsePath$hash = _parsePath.hash,
|
|
388
|
-
hash = _parsePath$hash === void 0 ? '' : _parsePath$hash;
|
|
389
|
-
|
|
390
|
-
var state = globalHistory.state || {};
|
|
391
|
-
return [state.idx, readOnly({
|
|
392
|
-
pathname: pathname,
|
|
393
|
-
search: search,
|
|
394
|
-
hash: hash,
|
|
395
|
-
state: state.usr || null,
|
|
396
|
-
key: state.key || 'default'
|
|
397
|
-
})];
|
|
205
|
+
// Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
206
|
+
function isPlainObject(o) {
|
|
207
|
+
if (!hasObjectPrototype(o)) {
|
|
208
|
+
return false;
|
|
398
209
|
}
|
|
399
210
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
blockers.call(blockedPopTx);
|
|
405
|
-
blockedPopTx = null;
|
|
406
|
-
} else {
|
|
407
|
-
var nextAction = Action.Pop;
|
|
408
|
-
|
|
409
|
-
var _getIndexAndLocation4 = getIndexAndLocation(),
|
|
410
|
-
nextIndex = _getIndexAndLocation4[0],
|
|
411
|
-
nextLocation = _getIndexAndLocation4[1];
|
|
412
|
-
|
|
413
|
-
if (blockers.length) {
|
|
414
|
-
if (nextIndex != null) {
|
|
415
|
-
var delta = index - nextIndex;
|
|
416
|
-
|
|
417
|
-
if (delta) {
|
|
418
|
-
// Revert the POP
|
|
419
|
-
blockedPopTx = {
|
|
420
|
-
action: nextAction,
|
|
421
|
-
location: nextLocation,
|
|
422
|
-
retry: function retry() {
|
|
423
|
-
go(delta * -1);
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
go(delta);
|
|
427
|
-
}
|
|
428
|
-
} else {
|
|
429
|
-
// Trying to POP to a location with no index. We did not create
|
|
430
|
-
// this location, so we can't effectively block the navigation.
|
|
431
|
-
process.env.NODE_ENV !== "production" ? warning$1(false, // TODO: Write up a doc that explains our blocking strategy in
|
|
432
|
-
// detail and link to it here so people can understand better
|
|
433
|
-
// what is going on and how to avoid it.
|
|
434
|
-
"You are trying to block a POP navigation to a location that was not " + "created by the history library. The block will fail silently in " + "production, but in general you should do all navigation with the " + "history library (instead of using window.history.pushState directly) " + "to avoid this situation.") : void 0;
|
|
435
|
-
}
|
|
436
|
-
} else {
|
|
437
|
-
applyTx(nextAction);
|
|
438
|
-
}
|
|
439
|
-
}
|
|
211
|
+
// If has modified constructor
|
|
212
|
+
const ctor = o.constructor;
|
|
213
|
+
if (typeof ctor === 'undefined') {
|
|
214
|
+
return true;
|
|
440
215
|
}
|
|
441
216
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
var _getIndexAndLocation5 = getIndexAndLocation(),
|
|
447
|
-
nextLocation = _getIndexAndLocation5[1]; // Ignore extraneous hashchange events.
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (createPath(nextLocation) !== createPath(location)) {
|
|
451
|
-
handlePop();
|
|
452
|
-
}
|
|
453
|
-
});
|
|
454
|
-
var action = Action.Pop;
|
|
455
|
-
|
|
456
|
-
var _getIndexAndLocation6 = getIndexAndLocation(),
|
|
457
|
-
index = _getIndexAndLocation6[0],
|
|
458
|
-
location = _getIndexAndLocation6[1];
|
|
459
|
-
|
|
460
|
-
var listeners = createEvents();
|
|
461
|
-
var blockers = createEvents();
|
|
462
|
-
|
|
463
|
-
if (index == null) {
|
|
464
|
-
index = 0;
|
|
465
|
-
globalHistory.replaceState(_extends$1({}, globalHistory.state, {
|
|
466
|
-
idx: index
|
|
467
|
-
}), '');
|
|
217
|
+
// If has modified prototype
|
|
218
|
+
const prot = ctor.prototype;
|
|
219
|
+
if (!hasObjectPrototype(prot)) {
|
|
220
|
+
return false;
|
|
468
221
|
}
|
|
469
222
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
if (base && base.getAttribute('href')) {
|
|
475
|
-
var url = window.location.href;
|
|
476
|
-
var hashIndex = url.indexOf('#');
|
|
477
|
-
href = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return href;
|
|
223
|
+
// If constructor does not have an Object-specific method
|
|
224
|
+
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
|
225
|
+
return false;
|
|
481
226
|
}
|
|
482
227
|
|
|
483
|
-
|
|
484
|
-
|
|
228
|
+
// Most likely a plain Object
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
function hasObjectPrototype(o) {
|
|
232
|
+
return Object.prototype.toString.call(o) === '[object Object]';
|
|
233
|
+
}
|
|
234
|
+
function deepEqual(a, b, partial = false) {
|
|
235
|
+
if (a === b) {
|
|
236
|
+
return true;
|
|
485
237
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
238
|
+
if (typeof a !== typeof b) {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
242
|
+
const aKeys = Object.keys(a);
|
|
243
|
+
const bKeys = Object.keys(b);
|
|
244
|
+
if (!partial && aKeys.length !== bKeys.length) {
|
|
245
|
+
return false;
|
|
490
246
|
}
|
|
491
|
-
|
|
492
|
-
return readOnly(_extends$1({
|
|
493
|
-
pathname: location.pathname,
|
|
494
|
-
hash: '',
|
|
495
|
-
search: ''
|
|
496
|
-
}, typeof to === 'string' ? parsePath(to) : to, {
|
|
497
|
-
state: state,
|
|
498
|
-
key: createKey()
|
|
499
|
-
}));
|
|
247
|
+
return !bKeys.some(key => !(key in a) || !deepEqual(a[key], b[key], partial));
|
|
500
248
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
return [{
|
|
504
|
-
usr: nextLocation.state,
|
|
505
|
-
key: nextLocation.key,
|
|
506
|
-
idx: index
|
|
507
|
-
}, createHref(nextLocation)];
|
|
249
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
250
|
+
return !a.some((item, index) => !deepEqual(item, b[index], partial));
|
|
508
251
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
function useStableCallback(fn) {
|
|
255
|
+
const fnRef = React.useRef(fn);
|
|
256
|
+
fnRef.current = fn;
|
|
257
|
+
const ref = React.useRef((...args) => fnRef.current(...args));
|
|
258
|
+
return ref.current;
|
|
259
|
+
}
|
|
260
|
+
function shallow(objA, objB) {
|
|
261
|
+
if (Object.is(objA, objB)) {
|
|
262
|
+
return true;
|
|
516
263
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
action = nextAction;
|
|
520
|
-
|
|
521
|
-
var _getIndexAndLocation7 = getIndexAndLocation();
|
|
522
|
-
|
|
523
|
-
index = _getIndexAndLocation7[0];
|
|
524
|
-
location = _getIndexAndLocation7[1];
|
|
525
|
-
listeners.call({
|
|
526
|
-
action: action,
|
|
527
|
-
location: location
|
|
528
|
-
});
|
|
264
|
+
if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
|
|
265
|
+
return false;
|
|
529
266
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
var nextLocation = getNextLocation(to, state);
|
|
534
|
-
|
|
535
|
-
function retry() {
|
|
536
|
-
push(to, state);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
process.env.NODE_ENV !== "production" ? warning$1(nextLocation.pathname.charAt(0) === '/', "Relative pathnames are not supported in hash history.push(" + JSON.stringify(to) + ")") : void 0;
|
|
540
|
-
|
|
541
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
542
|
-
var _getHistoryStateAndUr3 = getHistoryStateAndUrl(nextLocation, index + 1),
|
|
543
|
-
historyState = _getHistoryStateAndUr3[0],
|
|
544
|
-
url = _getHistoryStateAndUr3[1]; // TODO: Support forced reloading
|
|
545
|
-
// try...catch because iOS limits us to 100 pushState calls :/
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
try {
|
|
549
|
-
globalHistory.pushState(historyState, '', url);
|
|
550
|
-
} catch (error) {
|
|
551
|
-
// They are going to lose state here, but there is no real
|
|
552
|
-
// way to warn them about it since the page will refresh...
|
|
553
|
-
window.location.assign(url);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
applyTx(nextAction);
|
|
557
|
-
}
|
|
267
|
+
const keysA = Object.keys(objA);
|
|
268
|
+
if (keysA.length !== Object.keys(objB).length) {
|
|
269
|
+
return false;
|
|
558
270
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
var nextLocation = getNextLocation(to, state);
|
|
563
|
-
|
|
564
|
-
function retry() {
|
|
565
|
-
replace(to, state);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
process.env.NODE_ENV !== "production" ? warning$1(nextLocation.pathname.charAt(0) === '/', "Relative pathnames are not supported in hash history.replace(" + JSON.stringify(to) + ")") : void 0;
|
|
569
|
-
|
|
570
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
571
|
-
var _getHistoryStateAndUr4 = getHistoryStateAndUrl(nextLocation, index),
|
|
572
|
-
historyState = _getHistoryStateAndUr4[0],
|
|
573
|
-
url = _getHistoryStateAndUr4[1]; // TODO: Support forced reloading
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
globalHistory.replaceState(historyState, '', url);
|
|
577
|
-
applyTx(nextAction);
|
|
271
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
272
|
+
if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
|
|
273
|
+
return false;
|
|
578
274
|
}
|
|
579
275
|
}
|
|
580
|
-
|
|
581
|
-
function go(delta) {
|
|
582
|
-
globalHistory.go(delta);
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
var history = {
|
|
586
|
-
get action() {
|
|
587
|
-
return action;
|
|
588
|
-
},
|
|
589
|
-
|
|
590
|
-
get location() {
|
|
591
|
-
return location;
|
|
592
|
-
},
|
|
593
|
-
|
|
594
|
-
createHref: createHref,
|
|
595
|
-
push: push,
|
|
596
|
-
replace: replace,
|
|
597
|
-
go: go,
|
|
598
|
-
back: function back() {
|
|
599
|
-
go(-1);
|
|
600
|
-
},
|
|
601
|
-
forward: function forward() {
|
|
602
|
-
go(1);
|
|
603
|
-
},
|
|
604
|
-
listen: function listen(listener) {
|
|
605
|
-
return listeners.push(listener);
|
|
606
|
-
},
|
|
607
|
-
block: function block(blocker) {
|
|
608
|
-
var unblock = blockers.push(blocker);
|
|
609
|
-
|
|
610
|
-
if (blockers.length === 1) {
|
|
611
|
-
window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
return function () {
|
|
615
|
-
unblock(); // Remove the beforeunload listener so the document may
|
|
616
|
-
// still be salvageable in the pagehide event.
|
|
617
|
-
// See https://html.spec.whatwg.org/#unloading-documents
|
|
618
|
-
|
|
619
|
-
if (!blockers.length) {
|
|
620
|
-
window.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
621
|
-
}
|
|
622
|
-
};
|
|
623
|
-
}
|
|
624
|
-
};
|
|
625
|
-
return history;
|
|
276
|
+
return true;
|
|
626
277
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#creatememoryhistory
|
|
632
|
-
*/
|
|
633
|
-
|
|
634
|
-
function createMemoryHistory(options) {
|
|
635
|
-
if (options === void 0) {
|
|
636
|
-
options = {};
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
var _options3 = options,
|
|
640
|
-
_options3$initialEntr = _options3.initialEntries,
|
|
641
|
-
initialEntries = _options3$initialEntr === void 0 ? ['/'] : _options3$initialEntr,
|
|
642
|
-
initialIndex = _options3.initialIndex;
|
|
643
|
-
var entries = initialEntries.map(function (entry) {
|
|
644
|
-
var location = readOnly(_extends$1({
|
|
645
|
-
pathname: '/',
|
|
646
|
-
search: '',
|
|
647
|
-
hash: '',
|
|
648
|
-
state: null,
|
|
649
|
-
key: createKey()
|
|
650
|
-
}, typeof entry === 'string' ? parsePath(entry) : entry));
|
|
651
|
-
process.env.NODE_ENV !== "production" ? warning$1(location.pathname.charAt(0) === '/', "Relative pathnames are not supported in createMemoryHistory({ initialEntries }) (invalid entry: " + JSON.stringify(entry) + ")") : void 0;
|
|
652
|
-
return location;
|
|
278
|
+
function useRouteContext(opts) {
|
|
279
|
+
return useMatch({
|
|
280
|
+
...opts,
|
|
281
|
+
select: match => opts?.select ? opts.select(match.context) : match.context
|
|
653
282
|
});
|
|
654
|
-
var index = clamp(initialIndex == null ? entries.length - 1 : initialIndex, 0, entries.length - 1);
|
|
655
|
-
var action = Action.Pop;
|
|
656
|
-
var location = entries[index];
|
|
657
|
-
var listeners = createEvents();
|
|
658
|
-
var blockers = createEvents();
|
|
659
|
-
|
|
660
|
-
function createHref(to) {
|
|
661
|
-
return typeof to === 'string' ? to : createPath(to);
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
function getNextLocation(to, state) {
|
|
665
|
-
if (state === void 0) {
|
|
666
|
-
state = null;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
return readOnly(_extends$1({
|
|
670
|
-
pathname: location.pathname,
|
|
671
|
-
search: '',
|
|
672
|
-
hash: ''
|
|
673
|
-
}, typeof to === 'string' ? parsePath(to) : to, {
|
|
674
|
-
state: state,
|
|
675
|
-
key: createKey()
|
|
676
|
-
}));
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
function allowTx(action, location, retry) {
|
|
680
|
-
return !blockers.length || (blockers.call({
|
|
681
|
-
action: action,
|
|
682
|
-
location: location,
|
|
683
|
-
retry: retry
|
|
684
|
-
}), false);
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
function applyTx(nextAction, nextLocation) {
|
|
688
|
-
action = nextAction;
|
|
689
|
-
location = nextLocation;
|
|
690
|
-
listeners.call({
|
|
691
|
-
action: action,
|
|
692
|
-
location: location
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
function push(to, state) {
|
|
697
|
-
var nextAction = Action.Push;
|
|
698
|
-
var nextLocation = getNextLocation(to, state);
|
|
699
|
-
|
|
700
|
-
function retry() {
|
|
701
|
-
push(to, state);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
process.env.NODE_ENV !== "production" ? warning$1(location.pathname.charAt(0) === '/', "Relative pathnames are not supported in memory history.push(" + JSON.stringify(to) + ")") : void 0;
|
|
705
|
-
|
|
706
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
707
|
-
index += 1;
|
|
708
|
-
entries.splice(index, entries.length, nextLocation);
|
|
709
|
-
applyTx(nextAction, nextLocation);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
function replace(to, state) {
|
|
714
|
-
var nextAction = Action.Replace;
|
|
715
|
-
var nextLocation = getNextLocation(to, state);
|
|
716
|
-
|
|
717
|
-
function retry() {
|
|
718
|
-
replace(to, state);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
process.env.NODE_ENV !== "production" ? warning$1(location.pathname.charAt(0) === '/', "Relative pathnames are not supported in memory history.replace(" + JSON.stringify(to) + ")") : void 0;
|
|
722
|
-
|
|
723
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
724
|
-
entries[index] = nextLocation;
|
|
725
|
-
applyTx(nextAction, nextLocation);
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
function go(delta) {
|
|
730
|
-
var nextIndex = clamp(index + delta, 0, entries.length - 1);
|
|
731
|
-
var nextAction = Action.Pop;
|
|
732
|
-
var nextLocation = entries[nextIndex];
|
|
733
|
-
|
|
734
|
-
function retry() {
|
|
735
|
-
go(delta);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
739
|
-
index = nextIndex;
|
|
740
|
-
applyTx(nextAction, nextLocation);
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
var history = {
|
|
745
|
-
get index() {
|
|
746
|
-
return index;
|
|
747
|
-
},
|
|
748
|
-
|
|
749
|
-
get action() {
|
|
750
|
-
return action;
|
|
751
|
-
},
|
|
752
|
-
|
|
753
|
-
get location() {
|
|
754
|
-
return location;
|
|
755
|
-
},
|
|
756
|
-
|
|
757
|
-
createHref: createHref,
|
|
758
|
-
push: push,
|
|
759
|
-
replace: replace,
|
|
760
|
-
go: go,
|
|
761
|
-
back: function back() {
|
|
762
|
-
go(-1);
|
|
763
|
-
},
|
|
764
|
-
forward: function forward() {
|
|
765
|
-
go(1);
|
|
766
|
-
},
|
|
767
|
-
listen: function listen(listener) {
|
|
768
|
-
return listeners.push(listener);
|
|
769
|
-
},
|
|
770
|
-
block: function block(blocker) {
|
|
771
|
-
return blockers.push(blocker);
|
|
772
|
-
}
|
|
773
|
-
};
|
|
774
|
-
return history;
|
|
775
|
-
} ////////////////////////////////////////////////////////////////////////////////
|
|
776
|
-
// UTILS
|
|
777
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
778
|
-
|
|
779
|
-
function clamp(n, lowerBound, upperBound) {
|
|
780
|
-
return Math.min(Math.max(n, lowerBound), upperBound);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
function promptBeforeUnload(event) {
|
|
784
|
-
// Cancel the event.
|
|
785
|
-
event.preventDefault(); // Chrome (and legacy IE) requires returnValue to be set.
|
|
786
|
-
|
|
787
|
-
event.returnValue = '';
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
function createEvents() {
|
|
791
|
-
var handlers = [];
|
|
792
|
-
return {
|
|
793
|
-
get length() {
|
|
794
|
-
return handlers.length;
|
|
795
|
-
},
|
|
796
|
-
|
|
797
|
-
push: function push(fn) {
|
|
798
|
-
handlers.push(fn);
|
|
799
|
-
return function () {
|
|
800
|
-
handlers = handlers.filter(function (handler) {
|
|
801
|
-
return handler !== fn;
|
|
802
|
-
});
|
|
803
|
-
};
|
|
804
|
-
},
|
|
805
|
-
call: function call(arg) {
|
|
806
|
-
handlers.forEach(function (fn) {
|
|
807
|
-
return fn && fn(arg);
|
|
808
|
-
});
|
|
809
|
-
}
|
|
810
|
-
};
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
function createKey() {
|
|
814
|
-
return Math.random().toString(36).substr(2, 8);
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Creates a string URL path from the given pathname, search, and hash components.
|
|
818
|
-
*
|
|
819
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createpath
|
|
820
|
-
*/
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
function createPath(_ref) {
|
|
824
|
-
var _ref$pathname = _ref.pathname,
|
|
825
|
-
pathname = _ref$pathname === void 0 ? '/' : _ref$pathname,
|
|
826
|
-
_ref$search = _ref.search,
|
|
827
|
-
search = _ref$search === void 0 ? '' : _ref$search,
|
|
828
|
-
_ref$hash = _ref.hash,
|
|
829
|
-
hash = _ref$hash === void 0 ? '' : _ref$hash;
|
|
830
|
-
if (search && search !== '?') pathname += search.charAt(0) === '?' ? search : '?' + search;
|
|
831
|
-
if (hash && hash !== '#') pathname += hash.charAt(0) === '#' ? hash : '#' + hash;
|
|
832
|
-
return pathname;
|
|
833
|
-
}
|
|
834
|
-
/**
|
|
835
|
-
* Parses a string URL path into its separate pathname, search, and hash components.
|
|
836
|
-
*
|
|
837
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#parsepath
|
|
838
|
-
*/
|
|
839
|
-
|
|
840
|
-
function parsePath(path) {
|
|
841
|
-
var parsedPath = {};
|
|
842
|
-
|
|
843
|
-
if (path) {
|
|
844
|
-
var hashIndex = path.indexOf('#');
|
|
845
|
-
|
|
846
|
-
if (hashIndex >= 0) {
|
|
847
|
-
parsedPath.hash = path.substr(hashIndex);
|
|
848
|
-
path = path.substr(0, hashIndex);
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
var searchIndex = path.indexOf('?');
|
|
852
|
-
|
|
853
|
-
if (searchIndex >= 0) {
|
|
854
|
-
parsedPath.search = path.substr(searchIndex);
|
|
855
|
-
path = path.substr(0, searchIndex);
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
if (path) {
|
|
859
|
-
parsedPath.pathname = path;
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
return parsedPath;
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
var isProduction = process.env.NODE_ENV === 'production';
|
|
867
|
-
var prefix = 'Invariant failed';
|
|
868
|
-
function invariant(condition, message) {
|
|
869
|
-
if (condition) {
|
|
870
|
-
return;
|
|
871
|
-
}
|
|
872
|
-
if (isProduction) {
|
|
873
|
-
throw new Error(prefix);
|
|
874
|
-
}
|
|
875
|
-
var provided = typeof message === 'function' ? message() : message;
|
|
876
|
-
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
877
|
-
throw new Error(value);
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
// type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
881
|
-
// k: infer I,
|
|
882
|
-
// ) => any
|
|
883
|
-
// ? I
|
|
884
|
-
// : never
|
|
885
|
-
|
|
886
|
-
/**
|
|
887
|
-
* This function returns `a` if `b` is deeply equal.
|
|
888
|
-
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
889
|
-
* This can be used for structural sharing between JSON values for example.
|
|
890
|
-
*/
|
|
891
|
-
function replaceEqualDeep(prev, next) {
|
|
892
|
-
if (prev === next) {
|
|
893
|
-
return prev;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
const array = Array.isArray(prev) && Array.isArray(next);
|
|
897
|
-
|
|
898
|
-
if (array || isPlainObject(prev) && isPlainObject(next)) {
|
|
899
|
-
const aSize = array ? prev.length : Object.keys(prev).length;
|
|
900
|
-
const bItems = array ? next : Object.keys(next);
|
|
901
|
-
const bSize = bItems.length;
|
|
902
|
-
const copy = array ? [] : {};
|
|
903
|
-
let equalItems = 0;
|
|
904
|
-
|
|
905
|
-
for (let i = 0; i < bSize; i++) {
|
|
906
|
-
const key = array ? i : bItems[i];
|
|
907
|
-
copy[key] = replaceEqualDeep(prev[key], next[key]);
|
|
908
|
-
|
|
909
|
-
if (copy[key] === prev[key]) {
|
|
910
|
-
equalItems++;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
return aSize === bSize && equalItems === aSize ? prev : copy;
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
return next;
|
|
918
|
-
} // Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
919
|
-
|
|
920
|
-
function isPlainObject(o) {
|
|
921
|
-
if (!hasObjectPrototype(o)) {
|
|
922
|
-
return false;
|
|
923
|
-
} // If has modified constructor
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
const ctor = o.constructor;
|
|
927
|
-
|
|
928
|
-
if (typeof ctor === 'undefined') {
|
|
929
|
-
return true;
|
|
930
|
-
} // If has modified prototype
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
const prot = ctor.prototype;
|
|
934
|
-
|
|
935
|
-
if (!hasObjectPrototype(prot)) {
|
|
936
|
-
return false;
|
|
937
|
-
} // If constructor does not have an Object-specific method
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
|
941
|
-
return false;
|
|
942
|
-
} // Most likely a plain Object
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
return true;
|
|
946
283
|
}
|
|
947
|
-
|
|
948
|
-
function
|
|
949
|
-
return
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
function last(arr) {
|
|
953
|
-
return arr[arr.length - 1];
|
|
954
|
-
}
|
|
955
|
-
function warning(cond, message) {
|
|
956
|
-
if (cond) {
|
|
957
|
-
if (typeof console !== 'undefined') console.warn(message);
|
|
958
|
-
|
|
959
|
-
try {
|
|
960
|
-
throw new Error(message);
|
|
961
|
-
} catch (_unused) {}
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
return true;
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
function isFunction(d) {
|
|
968
|
-
return typeof d === 'function';
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
function functionalUpdate(updater, previous) {
|
|
972
|
-
if (isFunction(updater)) {
|
|
973
|
-
return updater(previous);
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
return updater;
|
|
977
|
-
}
|
|
978
|
-
function pick(parent, keys) {
|
|
979
|
-
return keys.reduce((obj, key) => {
|
|
980
|
-
obj[key] = parent[key];
|
|
981
|
-
return obj;
|
|
982
|
-
}, {});
|
|
284
|
+
const useLayoutEffect$1 = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
285
|
+
function escapeJSON(jsonString) {
|
|
286
|
+
return jsonString.replace(/\\/g, '\\\\') // Escape backslashes
|
|
287
|
+
.replace(/'/g, "\\'") // Escape single quotes
|
|
288
|
+
.replace(/"/g, '\\"'); // Escape double quotes
|
|
983
289
|
}
|
|
984
290
|
|
|
985
291
|
function joinPaths(paths) {
|
|
@@ -999,8 +305,8 @@ function trimPath(path) {
|
|
|
999
305
|
return trimPathRight(trimPathLeft(path));
|
|
1000
306
|
}
|
|
1001
307
|
function resolvePath(basepath, base, to) {
|
|
1002
|
-
base = base.replace(new RegExp(
|
|
1003
|
-
to = to.replace(new RegExp(
|
|
308
|
+
base = base.replace(new RegExp(`^${basepath}`), '/');
|
|
309
|
+
to = to.replace(new RegExp(`^${basepath}`), '/');
|
|
1004
310
|
let baseSegments = parsePathname(base);
|
|
1005
311
|
const toSegments = parsePathname(to);
|
|
1006
312
|
toSegments.forEach((toSegment, index) => {
|
|
@@ -1013,13 +319,10 @@ function resolvePath(basepath, base, to) {
|
|
|
1013
319
|
baseSegments.push(toSegment);
|
|
1014
320
|
} else ;
|
|
1015
321
|
} else if (toSegment.value === '..') {
|
|
1016
|
-
var _last;
|
|
1017
|
-
|
|
1018
322
|
// Extra trailing slash? pop it off
|
|
1019
|
-
if (baseSegments.length > 1 &&
|
|
323
|
+
if (baseSegments.length > 1 && last(baseSegments)?.value === '/') {
|
|
1020
324
|
baseSegments.pop();
|
|
1021
325
|
}
|
|
1022
|
-
|
|
1023
326
|
baseSegments.pop();
|
|
1024
327
|
} else if (toSegment.value === '.') {
|
|
1025
328
|
return;
|
|
@@ -1034,10 +337,8 @@ function parsePathname(pathname) {
|
|
|
1034
337
|
if (!pathname) {
|
|
1035
338
|
return [];
|
|
1036
339
|
}
|
|
1037
|
-
|
|
1038
340
|
pathname = cleanPath(pathname);
|
|
1039
341
|
const segments = [];
|
|
1040
|
-
|
|
1041
342
|
if (pathname.slice(0, 1) === '/') {
|
|
1042
343
|
pathname = pathname.substring(1);
|
|
1043
344
|
segments.push({
|
|
@@ -1045,34 +346,30 @@ function parsePathname(pathname) {
|
|
|
1045
346
|
value: '/'
|
|
1046
347
|
});
|
|
1047
348
|
}
|
|
1048
|
-
|
|
1049
349
|
if (!pathname) {
|
|
1050
350
|
return segments;
|
|
1051
|
-
}
|
|
1052
|
-
|
|
351
|
+
}
|
|
1053
352
|
|
|
353
|
+
// Remove empty segments and '.' segments
|
|
1054
354
|
const split = pathname.split('/').filter(Boolean);
|
|
1055
355
|
segments.push(...split.map(part => {
|
|
1056
|
-
if (part
|
|
356
|
+
if (part === '$' || part === '*') {
|
|
1057
357
|
return {
|
|
1058
358
|
type: 'wildcard',
|
|
1059
359
|
value: part
|
|
1060
360
|
};
|
|
1061
361
|
}
|
|
1062
|
-
|
|
1063
|
-
if (part.charAt(0) === ':') {
|
|
362
|
+
if (part.charAt(0) === '$') {
|
|
1064
363
|
return {
|
|
1065
364
|
type: 'param',
|
|
1066
365
|
value: part
|
|
1067
366
|
};
|
|
1068
367
|
}
|
|
1069
|
-
|
|
1070
368
|
return {
|
|
1071
369
|
type: 'pathname',
|
|
1072
370
|
value: part
|
|
1073
371
|
};
|
|
1074
372
|
}));
|
|
1075
|
-
|
|
1076
373
|
if (pathname.slice(-1) === '/') {
|
|
1077
374
|
pathname = pathname.substring(1);
|
|
1078
375
|
segments.push({
|
|
@@ -1080,66 +377,70 @@ function parsePathname(pathname) {
|
|
|
1080
377
|
value: '/'
|
|
1081
378
|
});
|
|
1082
379
|
}
|
|
1083
|
-
|
|
1084
380
|
return segments;
|
|
1085
381
|
}
|
|
1086
|
-
function interpolatePath(path, params,
|
|
382
|
+
function interpolatePath(path, params, leaveWildcards = false) {
|
|
1087
383
|
const interpolatedPathSegments = parsePathname(path);
|
|
1088
384
|
return joinPaths(interpolatedPathSegments.map(segment => {
|
|
1089
|
-
if (segment.
|
|
1090
|
-
|
|
385
|
+
if (segment.type === 'wildcard') {
|
|
386
|
+
const value = params[segment.value];
|
|
387
|
+
if (leaveWildcards) return `${segment.value}${value ?? ''}`;
|
|
388
|
+
return value;
|
|
1091
389
|
}
|
|
1092
|
-
|
|
1093
390
|
if (segment.type === 'param') {
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
|
|
391
|
+
return params[segment.value.substring(1)] ?? '';
|
|
1097
392
|
}
|
|
1098
|
-
|
|
1099
393
|
return segment.value;
|
|
1100
394
|
}));
|
|
1101
395
|
}
|
|
1102
|
-
function matchPathname(currentPathname, matchLocation) {
|
|
1103
|
-
const pathParams = matchByPath(currentPathname, matchLocation);
|
|
396
|
+
function matchPathname(basepath, currentPathname, matchLocation) {
|
|
397
|
+
const pathParams = matchByPath(basepath, currentPathname, matchLocation);
|
|
398
|
+
// const searchMatched = matchBySearch(location.search, matchLocation)
|
|
1104
399
|
|
|
1105
400
|
if (matchLocation.to && !pathParams) {
|
|
1106
401
|
return;
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
// }
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
return pathParams != null ? pathParams : {};
|
|
402
|
+
}
|
|
403
|
+
return pathParams ?? {};
|
|
1113
404
|
}
|
|
1114
|
-
function matchByPath(from, matchLocation) {
|
|
1115
|
-
|
|
1116
|
-
|
|
405
|
+
function matchByPath(basepath, from, matchLocation) {
|
|
406
|
+
// Remove the base path from the pathname
|
|
407
|
+
from = basepath != '/' ? from.substring(basepath.length) : from;
|
|
408
|
+
// Default to to $ (wildcard)
|
|
409
|
+
const to = `${matchLocation.to ?? '$'}`;
|
|
410
|
+
// Parse the from and to
|
|
1117
411
|
const baseSegments = parsePathname(from);
|
|
1118
|
-
const routeSegments = parsePathname(
|
|
412
|
+
const routeSegments = parsePathname(to);
|
|
413
|
+
if (!from.startsWith('/')) {
|
|
414
|
+
baseSegments.unshift({
|
|
415
|
+
type: 'pathname',
|
|
416
|
+
value: '/'
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
if (!to.startsWith('/')) {
|
|
420
|
+
routeSegments.unshift({
|
|
421
|
+
type: 'pathname',
|
|
422
|
+
value: '/'
|
|
423
|
+
});
|
|
424
|
+
}
|
|
1119
425
|
const params = {};
|
|
1120
|
-
|
|
1121
426
|
let isMatch = (() => {
|
|
1122
427
|
for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
|
|
1123
428
|
const baseSegment = baseSegments[i];
|
|
1124
429
|
const routeSegment = routeSegments[i];
|
|
1125
|
-
const
|
|
1126
|
-
const
|
|
1127
|
-
|
|
430
|
+
const isLastBaseSegment = i >= baseSegments.length - 1;
|
|
431
|
+
const isLastRouteSegment = i >= routeSegments.length - 1;
|
|
1128
432
|
if (routeSegment) {
|
|
1129
433
|
if (routeSegment.type === 'wildcard') {
|
|
1130
|
-
if (baseSegment
|
|
434
|
+
if (baseSegment?.value) {
|
|
1131
435
|
params['*'] = joinPaths(baseSegments.slice(i).map(d => d.value));
|
|
1132
436
|
return true;
|
|
1133
437
|
}
|
|
1134
|
-
|
|
1135
438
|
return false;
|
|
1136
439
|
}
|
|
1137
|
-
|
|
1138
440
|
if (routeSegment.type === 'pathname') {
|
|
1139
|
-
if (routeSegment.value === '/' && !
|
|
441
|
+
if (routeSegment.value === '/' && !baseSegment?.value) {
|
|
1140
442
|
return true;
|
|
1141
443
|
}
|
|
1142
|
-
|
|
1143
444
|
if (baseSegment) {
|
|
1144
445
|
if (matchLocation.caseSensitive) {
|
|
1145
446
|
if (routeSegment.value !== baseSegment.value) {
|
|
@@ -1150,1754 +451,2025 @@ function matchByPath(from, matchLocation) {
|
|
|
1150
451
|
}
|
|
1151
452
|
}
|
|
1152
453
|
}
|
|
1153
|
-
|
|
1154
454
|
if (!baseSegment) {
|
|
1155
455
|
return false;
|
|
1156
456
|
}
|
|
1157
|
-
|
|
1158
457
|
if (routeSegment.type === 'param') {
|
|
1159
|
-
if (
|
|
458
|
+
if (baseSegment?.value === '/') {
|
|
1160
459
|
return false;
|
|
1161
460
|
}
|
|
1162
|
-
|
|
1163
|
-
if (!baseSegment.value.startsWith(':')) {
|
|
461
|
+
if (baseSegment.value.charAt(0) !== '$') {
|
|
1164
462
|
params[routeSegment.value.substring(1)] = baseSegment.value;
|
|
1165
463
|
}
|
|
1166
464
|
}
|
|
1167
465
|
}
|
|
1168
|
-
|
|
1169
|
-
if (isLastRouteSegment && !isLastBaseSegment) {
|
|
466
|
+
if (!isLastBaseSegment && isLastRouteSegment) {
|
|
1170
467
|
return !!matchLocation.fuzzy;
|
|
1171
468
|
}
|
|
1172
469
|
}
|
|
1173
|
-
|
|
1174
470
|
return true;
|
|
1175
471
|
})();
|
|
1176
|
-
|
|
1177
472
|
return isMatch ? params : undefined;
|
|
1178
473
|
}
|
|
1179
474
|
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
tmp,
|
|
1186
|
-
str = '';
|
|
1187
|
-
|
|
1188
|
-
for (k in obj) {
|
|
1189
|
-
if ((tmp = obj[k]) !== void 0) {
|
|
1190
|
-
if (Array.isArray(tmp)) {
|
|
1191
|
-
for (i = 0; i < tmp.length; i++) {
|
|
1192
|
-
str && (str += '&');
|
|
1193
|
-
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
|
|
1194
|
-
}
|
|
1195
|
-
} else {
|
|
1196
|
-
str && (str += '&');
|
|
1197
|
-
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
|
|
1198
|
-
}
|
|
475
|
+
function useParams(opts) {
|
|
476
|
+
return useRouterState({
|
|
477
|
+
select: state => {
|
|
478
|
+
const params = last(state.matches)?.params;
|
|
479
|
+
return opts?.select ? opts.select(params) : params;
|
|
1199
480
|
}
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
return (pfx || '') + str;
|
|
481
|
+
});
|
|
1203
482
|
}
|
|
1204
483
|
|
|
1205
|
-
function
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
484
|
+
function useSearch(opts) {
|
|
485
|
+
return useMatch({
|
|
486
|
+
...opts,
|
|
487
|
+
select: match => {
|
|
488
|
+
return opts?.select ? opts.select(match.search) : match.search;
|
|
489
|
+
}
|
|
490
|
+
});
|
|
1212
491
|
}
|
|
1213
492
|
|
|
1214
|
-
|
|
1215
|
-
var tmp,
|
|
1216
|
-
k,
|
|
1217
|
-
out = {},
|
|
1218
|
-
arr = str.split('&');
|
|
493
|
+
const rootRouteId = '__root__';
|
|
1219
494
|
|
|
1220
|
-
|
|
1221
|
-
tmp = tmp.split('=');
|
|
1222
|
-
k = tmp.shift();
|
|
495
|
+
// The parse type here allows a zod schema to be passed directly to the validator
|
|
1223
496
|
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
} else {
|
|
1227
|
-
out[k] = toValue(tmp.shift());
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
497
|
+
class Route {
|
|
498
|
+
// Set up in this.init()
|
|
1230
499
|
|
|
1231
|
-
|
|
1232
|
-
}
|
|
500
|
+
// customId!: TCustomId
|
|
1233
501
|
|
|
1234
|
-
|
|
1235
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
1236
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
1237
|
-
var source = arguments[i];
|
|
502
|
+
// Optional
|
|
1238
503
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
504
|
+
constructor(options) {
|
|
505
|
+
this.options = options || {};
|
|
506
|
+
this.isRoot = !options?.getParentRoute;
|
|
507
|
+
Route.__onInit(this);
|
|
508
|
+
}
|
|
509
|
+
init = opts => {
|
|
510
|
+
this.originalIndex = opts.originalIndex;
|
|
511
|
+
const options = this.options;
|
|
512
|
+
const isRoot = !options?.path && !options?.id;
|
|
513
|
+
this.parentRoute = this.options?.getParentRoute?.();
|
|
514
|
+
if (isRoot) {
|
|
515
|
+
this.path = rootRouteId;
|
|
516
|
+
} else {
|
|
517
|
+
invariant(this.parentRoute, `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`);
|
|
1244
518
|
}
|
|
519
|
+
let path = isRoot ? rootRouteId : options.path;
|
|
1245
520
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
}
|
|
521
|
+
// If the path is anything other than an index path, trim it up
|
|
522
|
+
if (path && path !== '/') {
|
|
523
|
+
path = trimPath(path);
|
|
524
|
+
}
|
|
525
|
+
const customId = options?.id || path;
|
|
1250
526
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
path: routePath,
|
|
1256
|
-
fullPath
|
|
1257
|
-
} = routeConfig;
|
|
1258
|
-
|
|
1259
|
-
const action = router.state.actions[id] || (() => {
|
|
1260
|
-
router.state.actions[id] = {
|
|
1261
|
-
submissions: [],
|
|
1262
|
-
submit: async (submission, actionOpts) => {
|
|
1263
|
-
var _actionOpts$invalidat;
|
|
1264
|
-
|
|
1265
|
-
if (!route) {
|
|
1266
|
-
return;
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
|
-
const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
|
|
1270
|
-
|
|
1271
|
-
if (!(actionOpts != null && actionOpts.multi)) {
|
|
1272
|
-
action.submissions = action.submissions.filter(d => d.isMulti);
|
|
1273
|
-
}
|
|
1274
|
-
|
|
1275
|
-
const actionState = {
|
|
1276
|
-
submittedAt: Date.now(),
|
|
1277
|
-
status: 'pending',
|
|
1278
|
-
submission,
|
|
1279
|
-
isMulti: !!(actionOpts != null && actionOpts.multi)
|
|
1280
|
-
};
|
|
1281
|
-
action.current = actionState;
|
|
1282
|
-
action.latest = actionState;
|
|
1283
|
-
action.submissions.push(actionState);
|
|
1284
|
-
router.notify();
|
|
1285
|
-
|
|
1286
|
-
try {
|
|
1287
|
-
const res = await (route.options.action == null ? void 0 : route.options.action(submission));
|
|
1288
|
-
actionState.data = res;
|
|
1289
|
-
|
|
1290
|
-
if (invalidate) {
|
|
1291
|
-
router.invalidateRoute({
|
|
1292
|
-
to: '.',
|
|
1293
|
-
fromCurrent: true
|
|
1294
|
-
});
|
|
1295
|
-
await router.reload();
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
actionState.status = 'success';
|
|
1299
|
-
return res;
|
|
1300
|
-
} catch (err) {
|
|
1301
|
-
console.error(err);
|
|
1302
|
-
actionState.error = err;
|
|
1303
|
-
actionState.status = 'error';
|
|
1304
|
-
} finally {
|
|
1305
|
-
router.notify();
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
};
|
|
1309
|
-
return router.state.actions[id];
|
|
1310
|
-
})();
|
|
1311
|
-
|
|
1312
|
-
const loader = router.state.loaders[id] || (() => {
|
|
1313
|
-
router.state.loaders[id] = {
|
|
1314
|
-
pending: [],
|
|
1315
|
-
fetch: async loaderContext => {
|
|
1316
|
-
if (!route) {
|
|
1317
|
-
return;
|
|
1318
|
-
}
|
|
1319
|
-
|
|
1320
|
-
const loaderState = {
|
|
1321
|
-
loadedAt: Date.now(),
|
|
1322
|
-
loaderContext
|
|
1323
|
-
};
|
|
1324
|
-
loader.current = loaderState;
|
|
1325
|
-
loader.latest = loaderState;
|
|
1326
|
-
loader.pending.push(loaderState); // router.state = {
|
|
1327
|
-
// ...router.state,
|
|
1328
|
-
// currentAction: loaderState,
|
|
1329
|
-
// latestAction: loaderState,
|
|
1330
|
-
// }
|
|
1331
|
-
|
|
1332
|
-
router.notify();
|
|
1333
|
-
|
|
1334
|
-
try {
|
|
1335
|
-
return await (route.options.loader == null ? void 0 : route.options.loader(loaderContext));
|
|
1336
|
-
} finally {
|
|
1337
|
-
loader.pending = loader.pending.filter(d => d !== loaderState); // router.removeActionQueue.push({ loader, loaderState })
|
|
1338
|
-
|
|
1339
|
-
router.notify();
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
};
|
|
1343
|
-
return router.state.loaders[id];
|
|
1344
|
-
})();
|
|
1345
|
-
|
|
1346
|
-
let route = {
|
|
1347
|
-
routeId: id,
|
|
1348
|
-
routeRouteId: routeId,
|
|
1349
|
-
routePath,
|
|
1350
|
-
fullPath,
|
|
1351
|
-
options,
|
|
1352
|
-
router,
|
|
1353
|
-
childRoutes: undefined,
|
|
1354
|
-
parentRoute: parent,
|
|
1355
|
-
action,
|
|
1356
|
-
loader: loader,
|
|
1357
|
-
buildLink: options => {
|
|
1358
|
-
return router.buildLink(_extends({}, options, {
|
|
1359
|
-
from: fullPath
|
|
1360
|
-
}));
|
|
1361
|
-
},
|
|
1362
|
-
navigate: options => {
|
|
1363
|
-
return router.navigate(_extends({}, options, {
|
|
1364
|
-
from: fullPath
|
|
1365
|
-
}));
|
|
1366
|
-
},
|
|
1367
|
-
matchRoute: (matchLocation, opts) => {
|
|
1368
|
-
return router.matchRoute(_extends({}, matchLocation, {
|
|
1369
|
-
from: fullPath
|
|
1370
|
-
}), opts);
|
|
527
|
+
// Strip the parentId prefix from the first level of children
|
|
528
|
+
let id = isRoot ? rootRouteId : joinPaths([this.parentRoute.id === rootRouteId ? '' : this.parentRoute.id, customId]);
|
|
529
|
+
if (path === rootRouteId) {
|
|
530
|
+
path = '/';
|
|
1371
531
|
}
|
|
532
|
+
if (id !== rootRouteId) {
|
|
533
|
+
id = joinPaths(['/', id]);
|
|
534
|
+
}
|
|
535
|
+
const fullPath = id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path]);
|
|
536
|
+
this.path = path;
|
|
537
|
+
this.id = id;
|
|
538
|
+
// this.customId = customId as TCustomId
|
|
539
|
+
this.fullPath = fullPath;
|
|
540
|
+
this.to = fullPath;
|
|
541
|
+
};
|
|
542
|
+
addChildren = children => {
|
|
543
|
+
this.children = children;
|
|
544
|
+
return this;
|
|
545
|
+
};
|
|
546
|
+
update = options => {
|
|
547
|
+
Object.assign(this.options, options);
|
|
548
|
+
return this;
|
|
549
|
+
};
|
|
550
|
+
static __onInit = route => {
|
|
551
|
+
// This is a dummy static method that should get
|
|
552
|
+
// replaced by a framework specific implementation if necessary
|
|
553
|
+
};
|
|
554
|
+
useMatch = opts => {
|
|
555
|
+
return useMatch({
|
|
556
|
+
...opts,
|
|
557
|
+
from: this.id
|
|
558
|
+
});
|
|
559
|
+
};
|
|
560
|
+
useRouteContext = opts => {
|
|
561
|
+
return useMatch({
|
|
562
|
+
...opts,
|
|
563
|
+
from: this.id,
|
|
564
|
+
select: d => opts?.select ? opts.select(d.context) : d.context
|
|
565
|
+
});
|
|
566
|
+
};
|
|
567
|
+
useSearch = opts => {
|
|
568
|
+
return useSearch({
|
|
569
|
+
...opts,
|
|
570
|
+
from: this.id
|
|
571
|
+
});
|
|
572
|
+
};
|
|
573
|
+
useParams = opts => {
|
|
574
|
+
return useParams({
|
|
575
|
+
...opts,
|
|
576
|
+
from: this.id
|
|
577
|
+
});
|
|
578
|
+
};
|
|
579
|
+
useLoaderData = opts => {
|
|
580
|
+
return useLoaderData({
|
|
581
|
+
...opts,
|
|
582
|
+
from: this.id
|
|
583
|
+
});
|
|
1372
584
|
};
|
|
1373
|
-
router.options.createRoute == null ? void 0 : router.options.createRoute({
|
|
1374
|
-
router,
|
|
1375
|
-
route
|
|
1376
|
-
});
|
|
1377
|
-
return route;
|
|
1378
585
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
isRoot = true;
|
|
1388
|
-
}
|
|
1389
|
-
|
|
1390
|
-
if (isRoot) {
|
|
1391
|
-
options.path = rootRouteId;
|
|
1392
|
-
} // Strip the root from parentIds
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
if (parentId === rootRouteId) {
|
|
1396
|
-
parentId = '';
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
let path = isRoot ? rootRouteId : options.path; // If the path is anything other than an index path, trim it up
|
|
1400
|
-
|
|
1401
|
-
if (path && path !== '/') {
|
|
1402
|
-
path = trimPath(path);
|
|
586
|
+
function rootRouteWithContext() {
|
|
587
|
+
return options => {
|
|
588
|
+
return new RootRoute(options);
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
class RootRoute extends Route {
|
|
592
|
+
constructor(options) {
|
|
593
|
+
super(options);
|
|
1403
594
|
}
|
|
595
|
+
}
|
|
596
|
+
function createRouteMask(opts) {
|
|
597
|
+
return opts;
|
|
598
|
+
}
|
|
1404
599
|
|
|
1405
|
-
|
|
1406
|
-
let id = joinPaths([parentId, routeId]);
|
|
600
|
+
//
|
|
1407
601
|
|
|
1408
|
-
|
|
1409
|
-
|
|
602
|
+
function Matches() {
|
|
603
|
+
const {
|
|
604
|
+
routesById,
|
|
605
|
+
state
|
|
606
|
+
} = useRouter();
|
|
607
|
+
const {
|
|
608
|
+
matches
|
|
609
|
+
} = state;
|
|
610
|
+
const locationKey = useRouterState().location.state.key;
|
|
611
|
+
const route = routesById[rootRouteId];
|
|
612
|
+
const errorComponent = React.useCallback(props => {
|
|
613
|
+
return /*#__PURE__*/React.createElement(ErrorComponent, {
|
|
614
|
+
...props,
|
|
615
|
+
useMatch: route.useMatch,
|
|
616
|
+
useRouteContext: route.useRouteContext,
|
|
617
|
+
useSearch: route.useSearch,
|
|
618
|
+
useParams: route.useParams
|
|
619
|
+
});
|
|
620
|
+
}, [route]);
|
|
621
|
+
return /*#__PURE__*/React.createElement(matchesContext.Provider, {
|
|
622
|
+
value: matches
|
|
623
|
+
}, /*#__PURE__*/React.createElement(CatchBoundary, {
|
|
624
|
+
resetKey: locationKey,
|
|
625
|
+
errorComponent: errorComponent,
|
|
626
|
+
onCatch: () => {
|
|
627
|
+
warning(false, `Error in router! Consider setting an 'errorComponent' in your RootRoute! 👍`);
|
|
628
|
+
}
|
|
629
|
+
}, matches.length ? /*#__PURE__*/React.createElement(Match, {
|
|
630
|
+
matches: matches
|
|
631
|
+
}) : null));
|
|
632
|
+
}
|
|
633
|
+
const defaultPending = () => null;
|
|
634
|
+
function SafeFragment(props) {
|
|
635
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, props.children);
|
|
636
|
+
}
|
|
637
|
+
function Match({
|
|
638
|
+
matches
|
|
639
|
+
}) {
|
|
640
|
+
const {
|
|
641
|
+
options,
|
|
642
|
+
routesById
|
|
643
|
+
} = useRouter();
|
|
644
|
+
const match = matches[0];
|
|
645
|
+
const routeId = match?.routeId;
|
|
646
|
+
const route = routesById[routeId];
|
|
647
|
+
const locationKey = useRouterState().location.state?.key;
|
|
648
|
+
const PendingComponent = route.options.pendingComponent ?? options.defaultPendingComponent ?? defaultPending;
|
|
649
|
+
const routeErrorComponent = route.options.errorComponent ?? options.defaultErrorComponent ?? ErrorComponent;
|
|
650
|
+
const ResolvedSuspenseBoundary = route.options.wrapInSuspense ? React.Suspense : SafeFragment;
|
|
651
|
+
const errorComponent = routeErrorComponent ? React.useCallback(props => {
|
|
652
|
+
return /*#__PURE__*/React.createElement(routeErrorComponent, {
|
|
653
|
+
...props,
|
|
654
|
+
useMatch: route.useMatch,
|
|
655
|
+
useRouteContext: route.useRouteContext,
|
|
656
|
+
useSearch: route.useSearch,
|
|
657
|
+
useParams: route.useParams
|
|
658
|
+
});
|
|
659
|
+
}, [route]) : undefined;
|
|
660
|
+
return /*#__PURE__*/React.createElement(matchesContext.Provider, {
|
|
661
|
+
value: matches
|
|
662
|
+
}, /*#__PURE__*/React.createElement(ResolvedSuspenseBoundary, {
|
|
663
|
+
fallback: /*#__PURE__*/React.createElement(PendingComponent, {
|
|
664
|
+
useMatch: route.useMatch,
|
|
665
|
+
useRouteContext: route.useRouteContext,
|
|
666
|
+
useSearch: route.useSearch,
|
|
667
|
+
useParams: route.useParams
|
|
668
|
+
})
|
|
669
|
+
}, errorComponent ? /*#__PURE__*/React.createElement(CatchBoundary, {
|
|
670
|
+
resetKey: locationKey,
|
|
671
|
+
errorComponent: errorComponent,
|
|
672
|
+
onCatch: () => {
|
|
673
|
+
warning(false, `Error in route match: ${match.id}`);
|
|
674
|
+
}
|
|
675
|
+
}, /*#__PURE__*/React.createElement(MatchInner, {
|
|
676
|
+
match: match
|
|
677
|
+
})) : /*#__PURE__*/React.createElement(SafeFragment, null, /*#__PURE__*/React.createElement(MatchInner, {
|
|
678
|
+
match: match
|
|
679
|
+
}))));
|
|
680
|
+
}
|
|
681
|
+
function MatchInner({
|
|
682
|
+
match
|
|
683
|
+
}) {
|
|
684
|
+
const {
|
|
685
|
+
options,
|
|
686
|
+
routesById
|
|
687
|
+
} = useRouter();
|
|
688
|
+
const route = routesById[match.routeId];
|
|
689
|
+
if (match.status === 'error') {
|
|
690
|
+
throw match.error;
|
|
1410
691
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
id = joinPaths(['/', id]);
|
|
692
|
+
if (match.status === 'pending') {
|
|
693
|
+
throw match.loadPromise;
|
|
1414
694
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
createChildren: cb => createRouteConfig(options, cb(childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)), false, parentId, parentPath),
|
|
1425
|
-
addChildren: children => createRouteConfig(options, children, false, parentId, parentPath),
|
|
1426
|
-
createRoute: childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)
|
|
1427
|
-
};
|
|
1428
|
-
};
|
|
1429
|
-
|
|
1430
|
-
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
1431
|
-
function createRouteMatch(router, route, opts) {
|
|
1432
|
-
const routeMatch = _extends({}, route, opts, {
|
|
1433
|
-
router,
|
|
1434
|
-
routeSearch: {},
|
|
1435
|
-
search: {},
|
|
1436
|
-
childMatches: [],
|
|
1437
|
-
status: 'idle',
|
|
1438
|
-
routeLoaderData: {},
|
|
1439
|
-
loaderData: {},
|
|
1440
|
-
isFetching: false,
|
|
1441
|
-
isInvalid: false,
|
|
1442
|
-
invalidAt: Infinity,
|
|
1443
|
-
// pendingActions: [],
|
|
1444
|
-
getIsInvalid: () => {
|
|
1445
|
-
const now = Date.now();
|
|
1446
|
-
return routeMatch.isInvalid || routeMatch.invalidAt < now;
|
|
1447
|
-
},
|
|
1448
|
-
__: {
|
|
1449
|
-
abortController: new AbortController(),
|
|
1450
|
-
latestId: '',
|
|
1451
|
-
resolve: () => {},
|
|
1452
|
-
notify: () => {
|
|
1453
|
-
routeMatch.__.resolve();
|
|
1454
|
-
|
|
1455
|
-
routeMatch.router.notify();
|
|
1456
|
-
},
|
|
1457
|
-
validate: () => {
|
|
1458
|
-
var _routeMatch$parentMat, _routeMatch$parentMat2;
|
|
1459
|
-
|
|
1460
|
-
// Validate the search params and stabilize them
|
|
1461
|
-
const parentSearch = (_routeMatch$parentMat = (_routeMatch$parentMat2 = routeMatch.parentMatch) == null ? void 0 : _routeMatch$parentMat2.search) != null ? _routeMatch$parentMat : router.location.search;
|
|
1462
|
-
|
|
1463
|
-
try {
|
|
1464
|
-
var _validator;
|
|
1465
|
-
|
|
1466
|
-
const prevSearch = routeMatch.routeSearch;
|
|
1467
|
-
const validator = typeof routeMatch.options.validateSearch === 'object' ? routeMatch.options.validateSearch.parse : routeMatch.options.validateSearch;
|
|
1468
|
-
let nextSearch = replaceEqualDeep(prevSearch, (_validator = validator == null ? void 0 : validator(parentSearch)) != null ? _validator : {}); // Invalidate route matches when search param stability changes
|
|
1469
|
-
|
|
1470
|
-
if (prevSearch !== nextSearch) {
|
|
1471
|
-
routeMatch.isInvalid = true;
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
routeMatch.routeSearch = nextSearch;
|
|
1475
|
-
routeMatch.search = replaceEqualDeep(parentSearch, _extends({}, parentSearch, nextSearch));
|
|
1476
|
-
componentTypes.map(async type => {
|
|
1477
|
-
const component = routeMatch.options[type];
|
|
1478
|
-
|
|
1479
|
-
if (typeof routeMatch.__[type] !== 'function') {
|
|
1480
|
-
routeMatch.__[type] = component;
|
|
1481
|
-
}
|
|
1482
|
-
});
|
|
1483
|
-
} catch (err) {
|
|
1484
|
-
console.error(err);
|
|
1485
|
-
const error = new Error('Invalid search params found', {
|
|
1486
|
-
cause: err
|
|
1487
|
-
});
|
|
1488
|
-
error.code = 'INVALID_SEARCH_PARAMS';
|
|
1489
|
-
routeMatch.status = 'error';
|
|
1490
|
-
routeMatch.error = error; // Do not proceed with loading the route
|
|
1491
|
-
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
},
|
|
1496
|
-
cancel: () => {
|
|
1497
|
-
var _routeMatch$__$abortC;
|
|
1498
|
-
|
|
1499
|
-
(_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
|
|
1500
|
-
},
|
|
1501
|
-
invalidate: () => {
|
|
1502
|
-
routeMatch.isInvalid = true;
|
|
1503
|
-
},
|
|
1504
|
-
hasLoaders: () => {
|
|
1505
|
-
return !!(route.options.loader || componentTypes.some(d => {
|
|
1506
|
-
var _route$options$d;
|
|
1507
|
-
|
|
1508
|
-
return (_route$options$d = route.options[d]) == null ? void 0 : _route$options$d.preload;
|
|
1509
|
-
}));
|
|
1510
|
-
},
|
|
1511
|
-
load: async loaderOpts => {
|
|
1512
|
-
const now = Date.now();
|
|
1513
|
-
const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0; // If this is a preload, add it to the preload cache
|
|
1514
|
-
|
|
1515
|
-
if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
|
|
1516
|
-
// If the match is currently active, don't preload it
|
|
1517
|
-
if (router.state.matches.find(d => d.matchId === routeMatch.matchId)) {
|
|
1518
|
-
return;
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
|
-
router.matchCache[routeMatch.matchId] = {
|
|
1522
|
-
gc: now + loaderOpts.gcMaxAge,
|
|
1523
|
-
match: routeMatch
|
|
1524
|
-
};
|
|
1525
|
-
} // If the match is invalid, errored or idle, trigger it to load
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
if (routeMatch.status === 'success' && routeMatch.getIsInvalid() || routeMatch.status === 'error' || routeMatch.status === 'idle') {
|
|
1529
|
-
const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
|
|
1530
|
-
await routeMatch.fetch({
|
|
1531
|
-
maxAge
|
|
1532
|
-
});
|
|
1533
|
-
}
|
|
1534
|
-
},
|
|
1535
|
-
fetch: async opts => {
|
|
1536
|
-
const loadId = '' + Date.now() + Math.random();
|
|
1537
|
-
routeMatch.__.latestId = loadId;
|
|
1538
|
-
|
|
1539
|
-
const checkLatest = async () => {
|
|
1540
|
-
if (loadId !== routeMatch.__.latestId) {
|
|
1541
|
-
// warning(true, 'Data loader is out of date!')
|
|
1542
|
-
return new Promise(() => {});
|
|
1543
|
-
}
|
|
1544
|
-
}; // If the match was in an error state, set it
|
|
1545
|
-
// to a loading state again. Otherwise, keep it
|
|
1546
|
-
// as loading or resolved
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
if (routeMatch.status === 'idle') {
|
|
1550
|
-
routeMatch.status = 'loading';
|
|
1551
|
-
} // We started loading the route, so it's no longer invalid
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
routeMatch.isInvalid = false;
|
|
1555
|
-
routeMatch.__.loadPromise = new Promise(async resolve => {
|
|
1556
|
-
// We are now fetching, even if it's in the background of a
|
|
1557
|
-
// resolved state
|
|
1558
|
-
routeMatch.isFetching = true;
|
|
1559
|
-
routeMatch.__.resolve = resolve;
|
|
1560
|
-
|
|
1561
|
-
routeMatch.__.componentsPromise = (async () => {
|
|
1562
|
-
// then run all component and data loaders in parallel
|
|
1563
|
-
// For each component type, potentially load it asynchronously
|
|
1564
|
-
await Promise.all(componentTypes.map(async type => {
|
|
1565
|
-
var _routeMatch$__$type;
|
|
1566
|
-
|
|
1567
|
-
const component = routeMatch.options[type];
|
|
1568
|
-
|
|
1569
|
-
if ((_routeMatch$__$type = routeMatch.__[type]) != null && _routeMatch$__$type.preload) {
|
|
1570
|
-
routeMatch.__[type] = await router.options.loadComponent(component);
|
|
1571
|
-
}
|
|
1572
|
-
}));
|
|
1573
|
-
})();
|
|
1574
|
-
|
|
1575
|
-
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
1576
|
-
try {
|
|
1577
|
-
var _ref, _ref2, _opts$maxAge;
|
|
1578
|
-
|
|
1579
|
-
if (routeMatch.options.loader) {
|
|
1580
|
-
const data = await router.loadMatchData(routeMatch);
|
|
1581
|
-
await checkLatest();
|
|
1582
|
-
routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
|
|
1583
|
-
}
|
|
1584
|
-
|
|
1585
|
-
routeMatch.error = undefined;
|
|
1586
|
-
routeMatch.status = 'success';
|
|
1587
|
-
routeMatch.updatedAt = Date.now();
|
|
1588
|
-
routeMatch.invalidAt = routeMatch.updatedAt + ((_ref = (_ref2 = (_opts$maxAge = opts == null ? void 0 : opts.maxAge) != null ? _opts$maxAge : routeMatch.options.loaderMaxAge) != null ? _ref2 : router.options.defaultLoaderMaxAge) != null ? _ref : 0);
|
|
1589
|
-
return routeMatch.routeLoaderData;
|
|
1590
|
-
} catch (err) {
|
|
1591
|
-
await checkLatest();
|
|
1592
|
-
|
|
1593
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
1594
|
-
console.error(err);
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
routeMatch.error = err;
|
|
1598
|
-
routeMatch.status = 'error';
|
|
1599
|
-
routeMatch.updatedAt = Date.now();
|
|
1600
|
-
throw err;
|
|
1601
|
-
}
|
|
1602
|
-
});
|
|
1603
|
-
|
|
1604
|
-
const after = async () => {
|
|
1605
|
-
await checkLatest();
|
|
1606
|
-
routeMatch.isFetching = false;
|
|
1607
|
-
delete routeMatch.__.loadPromise;
|
|
1608
|
-
|
|
1609
|
-
routeMatch.__.notify();
|
|
1610
|
-
};
|
|
1611
|
-
|
|
1612
|
-
try {
|
|
1613
|
-
await Promise.all([routeMatch.__.componentsPromise, routeMatch.__.dataPromise.catch(() => {})]);
|
|
1614
|
-
after();
|
|
1615
|
-
} catch (_unused) {
|
|
1616
|
-
after();
|
|
1617
|
-
}
|
|
695
|
+
if (match.status === 'success') {
|
|
696
|
+
let comp = route.options.component ?? options.defaultComponent;
|
|
697
|
+
if (comp) {
|
|
698
|
+
return /*#__PURE__*/React.createElement(comp, {
|
|
699
|
+
useMatch: route.useMatch,
|
|
700
|
+
useRouteContext: route.useRouteContext,
|
|
701
|
+
useSearch: route.useSearch,
|
|
702
|
+
useParams: route.useParams,
|
|
703
|
+
useLoaderData: route.useLoaderData
|
|
1618
704
|
});
|
|
1619
|
-
await routeMatch.__.loadPromise;
|
|
1620
|
-
await checkLatest();
|
|
1621
705
|
}
|
|
706
|
+
return /*#__PURE__*/React.createElement(Outlet, null);
|
|
707
|
+
}
|
|
708
|
+
invariant(false, 'Idle routeMatch status encountered during rendering! You should never see this. File an issue!');
|
|
709
|
+
}
|
|
710
|
+
function Outlet() {
|
|
711
|
+
const matches = React.useContext(matchesContext).slice(1);
|
|
712
|
+
if (!matches[0]) {
|
|
713
|
+
return null;
|
|
714
|
+
}
|
|
715
|
+
return /*#__PURE__*/React.createElement(Match, {
|
|
716
|
+
matches: matches
|
|
1622
717
|
});
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
718
|
+
}
|
|
719
|
+
function useMatchRoute() {
|
|
720
|
+
const {
|
|
721
|
+
matchRoute
|
|
722
|
+
} = useRouter();
|
|
723
|
+
return React.useCallback(opts => {
|
|
724
|
+
const {
|
|
725
|
+
pending,
|
|
726
|
+
caseSensitive,
|
|
727
|
+
...rest
|
|
728
|
+
} = opts;
|
|
729
|
+
return matchRoute(rest, {
|
|
730
|
+
pending,
|
|
731
|
+
caseSensitive
|
|
732
|
+
});
|
|
733
|
+
}, []);
|
|
734
|
+
}
|
|
735
|
+
function MatchRoute(props) {
|
|
736
|
+
const matchRoute = useMatchRoute();
|
|
737
|
+
const params = matchRoute(props);
|
|
738
|
+
if (typeof props.children === 'function') {
|
|
739
|
+
return props.children(params);
|
|
1626
740
|
}
|
|
1627
|
-
|
|
1628
|
-
return routeMatch;
|
|
741
|
+
return !!params ? props.children : null;
|
|
1629
742
|
}
|
|
1630
|
-
|
|
1631
|
-
const
|
|
1632
|
-
const
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
743
|
+
function useMatch(opts) {
|
|
744
|
+
const nearestMatch = React.useContext(matchesContext)[0];
|
|
745
|
+
const nearestMatchRouteId = nearestMatch?.routeId;
|
|
746
|
+
const matchRouteId = useRouterState({
|
|
747
|
+
select: state => {
|
|
748
|
+
const match = opts?.from ? state.matches.find(d => d.routeId === opts?.from) : state.matches.find(d => d.id === nearestMatch.id);
|
|
749
|
+
return match.routeId;
|
|
1637
750
|
}
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
} catch (err) {//
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
751
|
+
});
|
|
752
|
+
if (opts?.strict ?? true) {
|
|
753
|
+
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?`);
|
|
754
|
+
}
|
|
755
|
+
const matchSelection = useRouterState({
|
|
756
|
+
select: state => {
|
|
757
|
+
const match = opts?.from ? state.matches.find(d => d.routeId === opts?.from) : state.matches.find(d => d.id === nearestMatch.id);
|
|
758
|
+
invariant(match, `Could not find ${opts?.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`);
|
|
759
|
+
return opts?.select ? opts.select(match) : match;
|
|
1650
760
|
}
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
};
|
|
761
|
+
});
|
|
762
|
+
return matchSelection;
|
|
1654
763
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
if (typeof val === 'undefined' || val === undefined) {
|
|
1664
|
-
delete search[key];
|
|
1665
|
-
} else if (val && typeof val === 'object' && val !== null) {
|
|
1666
|
-
try {
|
|
1667
|
-
search[key] = stringify(val);
|
|
1668
|
-
} catch (err) {// silent
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
});
|
|
764
|
+
const matchesContext = /*#__PURE__*/React.createContext(null);
|
|
765
|
+
function useMatches(opts) {
|
|
766
|
+
const contextMatches = React.useContext(matchesContext);
|
|
767
|
+
return useRouterState({
|
|
768
|
+
select: state => {
|
|
769
|
+
const matches = state.matches.slice(state.matches.findIndex(d => d.id === contextMatches[0]?.id));
|
|
770
|
+
return opts?.select ? opts.select(matches) : matches;
|
|
1672
771
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
function useLoaderData(opts) {
|
|
775
|
+
const match = useMatch({
|
|
776
|
+
...opts,
|
|
777
|
+
select: undefined
|
|
778
|
+
});
|
|
779
|
+
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
1677
780
|
}
|
|
1678
781
|
|
|
1679
|
-
var _window$document;
|
|
1680
782
|
// Detect if we're in the DOM
|
|
1681
|
-
const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement); // This is the default history object if none is defined
|
|
1682
|
-
|
|
1683
|
-
const createDefaultHistory = () => isServer ? createMemoryHistory() : createBrowserHistory();
|
|
1684
783
|
|
|
1685
|
-
function
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
loaders: {},
|
|
1692
|
-
lastUpdated: Date.now(),
|
|
1693
|
-
isFetching: false,
|
|
1694
|
-
isPreloading: false
|
|
1695
|
-
};
|
|
784
|
+
function redirect(opts) {
|
|
785
|
+
opts.isRedirect = true;
|
|
786
|
+
return opts;
|
|
787
|
+
}
|
|
788
|
+
function isRedirect(obj) {
|
|
789
|
+
return !!obj?.isRedirect;
|
|
1696
790
|
}
|
|
1697
791
|
|
|
1698
|
-
|
|
1699
|
-
var _userOptions$stringif, _userOptions$parseSea;
|
|
1700
|
-
|
|
1701
|
-
const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
|
|
1702
|
-
|
|
1703
|
-
const originalOptions = _extends({
|
|
1704
|
-
defaultLoaderGcMaxAge: 5 * 60 * 1000,
|
|
1705
|
-
defaultLoaderMaxAge: 0,
|
|
1706
|
-
defaultPreloadMaxAge: 2000,
|
|
1707
|
-
defaultPreloadDelay: 50
|
|
1708
|
-
}, userOptions, {
|
|
1709
|
-
stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
|
|
1710
|
-
parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
|
|
1711
|
-
});
|
|
1712
|
-
|
|
1713
|
-
let router = {
|
|
1714
|
-
types: undefined,
|
|
1715
|
-
// public api
|
|
1716
|
-
history,
|
|
1717
|
-
options: originalOptions,
|
|
1718
|
-
listeners: [],
|
|
1719
|
-
// Resolved after construction
|
|
1720
|
-
basepath: '',
|
|
1721
|
-
routeTree: undefined,
|
|
1722
|
-
routesById: {},
|
|
1723
|
-
location: undefined,
|
|
1724
|
-
//
|
|
1725
|
-
navigationPromise: Promise.resolve(),
|
|
1726
|
-
resolveNavigation: () => {},
|
|
1727
|
-
matchCache: {},
|
|
1728
|
-
state: getInitialRouterState(),
|
|
1729
|
-
reset: () => {
|
|
1730
|
-
router.state = getInitialRouterState();
|
|
1731
|
-
router.notify();
|
|
1732
|
-
},
|
|
1733
|
-
startedLoadingAt: Date.now(),
|
|
1734
|
-
subscribe: listener => {
|
|
1735
|
-
router.listeners.push(listener);
|
|
1736
|
-
return () => {
|
|
1737
|
-
router.listeners = router.listeners.filter(x => x !== listener);
|
|
1738
|
-
};
|
|
1739
|
-
},
|
|
1740
|
-
getRoute: id => {
|
|
1741
|
-
return router.routesById[id];
|
|
1742
|
-
},
|
|
1743
|
-
notify: () => {
|
|
1744
|
-
const isFetching = router.state.status === 'loading' || router.state.matches.some(d => d.isFetching);
|
|
1745
|
-
const isPreloading = Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId));
|
|
1746
|
-
|
|
1747
|
-
if (router.state.isFetching !== isFetching || router.state.isPreloading !== isPreloading) {
|
|
1748
|
-
router.state = _extends({}, router.state, {
|
|
1749
|
-
isFetching,
|
|
1750
|
-
isPreloading
|
|
1751
|
-
});
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
cascadeLoaderData(router.state.matches);
|
|
1755
|
-
router.listeners.forEach(listener => listener(router));
|
|
1756
|
-
},
|
|
1757
|
-
dehydrateState: () => {
|
|
1758
|
-
return _extends({}, pick(router.state, ['status', 'location', 'lastUpdated']), {
|
|
1759
|
-
matches: router.state.matches.map(match => pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
|
|
1760
|
-
});
|
|
1761
|
-
},
|
|
1762
|
-
hydrateState: dehydratedState => {
|
|
1763
|
-
// Match the routes
|
|
1764
|
-
const matches = router.matchRoutes(router.location.pathname, {
|
|
1765
|
-
strictParseParams: true
|
|
1766
|
-
});
|
|
1767
|
-
matches.forEach((match, index) => {
|
|
1768
|
-
const dehydratedMatch = dehydratedState.matches[index];
|
|
1769
|
-
invariant(dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
|
|
1770
|
-
Object.assign(match, dehydratedMatch);
|
|
1771
|
-
});
|
|
1772
|
-
matches.forEach(match => match.__.validate());
|
|
1773
|
-
router.state = _extends({}, router.state, dehydratedState, {
|
|
1774
|
-
matches
|
|
1775
|
-
});
|
|
1776
|
-
},
|
|
1777
|
-
mount: () => {
|
|
1778
|
-
const next = router.__.buildLocation({
|
|
1779
|
-
to: '.',
|
|
1780
|
-
search: true,
|
|
1781
|
-
hash: true
|
|
1782
|
-
}); // If the current location isn't updated, trigger a navigation
|
|
1783
|
-
// to the current location. Otherwise, load the current location.
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
if (next.href !== router.location.href) {
|
|
1787
|
-
router.__.commitLocation(next, true);
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1790
|
-
if (!router.state.matches.length) {
|
|
1791
|
-
router.load();
|
|
1792
|
-
}
|
|
1793
|
-
|
|
1794
|
-
const unsub = router.history.listen(event => {
|
|
1795
|
-
router.load(router.__.parseLocation(event.location, router.location));
|
|
1796
|
-
}); // addEventListener does not exist in React Native, but window does
|
|
1797
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1798
|
-
|
|
1799
|
-
if (!isServer && window.addEventListener) {
|
|
1800
|
-
// Listen to visibillitychange and focus
|
|
1801
|
-
window.addEventListener('visibilitychange', router.onFocus, false);
|
|
1802
|
-
window.addEventListener('focus', router.onFocus, false);
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
|
-
return () => {
|
|
1806
|
-
unsub();
|
|
792
|
+
// @ts-nocheck
|
|
1807
793
|
|
|
1808
|
-
|
|
1809
|
-
// Be sure to unsubscribe if a new handler is set
|
|
1810
|
-
window.removeEventListener('visibilitychange', router.onFocus);
|
|
1811
|
-
window.removeEventListener('focus', router.onFocus);
|
|
1812
|
-
}
|
|
1813
|
-
};
|
|
1814
|
-
},
|
|
1815
|
-
onFocus: () => {
|
|
1816
|
-
router.load();
|
|
1817
|
-
},
|
|
1818
|
-
update: opts => {
|
|
1819
|
-
const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
|
|
794
|
+
// qss has been slightly modified and inlined here for our use cases (and compression's sake). We've included it as a hard dependency for MIT license attribution.
|
|
1820
795
|
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
796
|
+
function encode(obj, pfx) {
|
|
797
|
+
var k,
|
|
798
|
+
i,
|
|
799
|
+
tmp,
|
|
800
|
+
str = '';
|
|
801
|
+
for (k in obj) {
|
|
802
|
+
if ((tmp = obj[k]) !== void 0) {
|
|
803
|
+
if (Array.isArray(tmp)) {
|
|
804
|
+
for (i = 0; i < tmp.length; i++) {
|
|
805
|
+
str && (str += '&');
|
|
806
|
+
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
|
|
1824
807
|
}
|
|
1825
|
-
|
|
1826
|
-
router.location = router.__.parseLocation(router.history.location);
|
|
1827
|
-
router.state.location = router.location;
|
|
1828
|
-
}
|
|
1829
|
-
|
|
1830
|
-
Object.assign(router.options, opts);
|
|
1831
|
-
const {
|
|
1832
|
-
basepath,
|
|
1833
|
-
routeConfig
|
|
1834
|
-
} = router.options;
|
|
1835
|
-
router.basepath = cleanPath("/" + (basepath != null ? basepath : ''));
|
|
1836
|
-
|
|
1837
|
-
if (routeConfig) {
|
|
1838
|
-
router.routesById = {};
|
|
1839
|
-
router.routeTree = router.__.buildRouteTree(routeConfig);
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
return router;
|
|
1843
|
-
},
|
|
1844
|
-
cancelMatches: () => {
|
|
1845
|
-
var _router$state$pending, _router$state$pending2;
|
|
1846
|
-
[...router.state.matches, ...((_router$state$pending = (_router$state$pending2 = router.state.pending) == null ? void 0 : _router$state$pending2.matches) != null ? _router$state$pending : [])].forEach(match => {
|
|
1847
|
-
match.cancel();
|
|
1848
|
-
});
|
|
1849
|
-
},
|
|
1850
|
-
load: async next => {
|
|
1851
|
-
const id = Math.random();
|
|
1852
|
-
router.startedLoadingAt = id;
|
|
1853
|
-
|
|
1854
|
-
if (next) {
|
|
1855
|
-
// Ingest the new location
|
|
1856
|
-
router.location = next;
|
|
1857
|
-
} // Cancel any pending matches
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
router.cancelMatches(); // Match the routes
|
|
1861
|
-
|
|
1862
|
-
const matches = router.matchRoutes(router.location.pathname, {
|
|
1863
|
-
strictParseParams: true
|
|
1864
|
-
});
|
|
1865
|
-
|
|
1866
|
-
if (typeof document !== 'undefined') {
|
|
1867
|
-
router.state = _extends({}, router.state, {
|
|
1868
|
-
pending: {
|
|
1869
|
-
matches: matches,
|
|
1870
|
-
location: router.location
|
|
1871
|
-
},
|
|
1872
|
-
status: 'loading'
|
|
1873
|
-
});
|
|
1874
808
|
} else {
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
location: router.location,
|
|
1878
|
-
status: 'loading'
|
|
1879
|
-
});
|
|
1880
|
-
}
|
|
1881
|
-
|
|
1882
|
-
router.notify(); // Load the matches
|
|
1883
|
-
|
|
1884
|
-
await router.loadMatches(matches);
|
|
1885
|
-
|
|
1886
|
-
if (router.startedLoadingAt !== id) {
|
|
1887
|
-
// Ignore side-effects of match loading
|
|
1888
|
-
return router.navigationPromise;
|
|
1889
|
-
}
|
|
1890
|
-
|
|
1891
|
-
const previousMatches = router.state.matches;
|
|
1892
|
-
const exiting = [],
|
|
1893
|
-
staying = [];
|
|
1894
|
-
previousMatches.forEach(d => {
|
|
1895
|
-
if (matches.find(dd => dd.matchId === d.matchId)) {
|
|
1896
|
-
staying.push(d);
|
|
1897
|
-
} else {
|
|
1898
|
-
exiting.push(d);
|
|
1899
|
-
}
|
|
1900
|
-
});
|
|
1901
|
-
const entering = matches.filter(d => {
|
|
1902
|
-
return !previousMatches.find(dd => dd.matchId === d.matchId);
|
|
1903
|
-
});
|
|
1904
|
-
const now = Date.now();
|
|
1905
|
-
exiting.forEach(d => {
|
|
1906
|
-
var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
|
|
1907
|
-
|
|
1908
|
-
d.__.onExit == null ? void 0 : d.__.onExit({
|
|
1909
|
-
params: d.params,
|
|
1910
|
-
search: d.routeSearch
|
|
1911
|
-
}); // Clear idle error states when match leaves
|
|
1912
|
-
|
|
1913
|
-
if (d.status === 'error' && !d.isFetching) {
|
|
1914
|
-
d.status = 'idle';
|
|
1915
|
-
d.error = undefined;
|
|
1916
|
-
}
|
|
1917
|
-
|
|
1918
|
-
const gc = Math.max((_ref = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref : 0, (_ref2 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref2 : 0);
|
|
1919
|
-
|
|
1920
|
-
if (gc > 0) {
|
|
1921
|
-
router.matchCache[d.matchId] = {
|
|
1922
|
-
gc: gc == Infinity ? Number.MAX_SAFE_INTEGER : now + gc,
|
|
1923
|
-
match: d
|
|
1924
|
-
};
|
|
1925
|
-
}
|
|
1926
|
-
});
|
|
1927
|
-
staying.forEach(d => {
|
|
1928
|
-
d.options.onTransition == null ? void 0 : d.options.onTransition({
|
|
1929
|
-
params: d.params,
|
|
1930
|
-
search: d.routeSearch
|
|
1931
|
-
});
|
|
1932
|
-
});
|
|
1933
|
-
entering.forEach(d => {
|
|
1934
|
-
d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
|
|
1935
|
-
params: d.params,
|
|
1936
|
-
search: d.search
|
|
1937
|
-
});
|
|
1938
|
-
delete router.matchCache[d.matchId];
|
|
1939
|
-
});
|
|
1940
|
-
|
|
1941
|
-
if (router.startedLoadingAt !== id) {
|
|
1942
|
-
// Ignore side-effects of match loading
|
|
1943
|
-
return;
|
|
1944
|
-
}
|
|
1945
|
-
|
|
1946
|
-
matches.forEach(match => {
|
|
1947
|
-
// Clear actions
|
|
1948
|
-
if (match.action) {
|
|
1949
|
-
match.action.current = undefined;
|
|
1950
|
-
match.action.submissions = [];
|
|
1951
|
-
}
|
|
1952
|
-
});
|
|
1953
|
-
router.state = _extends({}, router.state, {
|
|
1954
|
-
location: router.location,
|
|
1955
|
-
matches,
|
|
1956
|
-
pending: undefined,
|
|
1957
|
-
status: 'idle'
|
|
1958
|
-
});
|
|
1959
|
-
router.notify();
|
|
1960
|
-
router.resolveNavigation();
|
|
1961
|
-
},
|
|
1962
|
-
cleanMatchCache: () => {
|
|
1963
|
-
const now = Date.now();
|
|
1964
|
-
Object.keys(router.matchCache).forEach(matchId => {
|
|
1965
|
-
const entry = router.matchCache[matchId]; // Don't remove loading matches
|
|
1966
|
-
|
|
1967
|
-
if (entry.match.status === 'loading') {
|
|
1968
|
-
return;
|
|
1969
|
-
} // Do not remove successful matches that are still valid
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
if (entry.gc > 0 && entry.gc > now) {
|
|
1973
|
-
return;
|
|
1974
|
-
} // Everything else gets removed
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
delete router.matchCache[matchId];
|
|
1978
|
-
});
|
|
1979
|
-
},
|
|
1980
|
-
loadRoute: async function loadRoute(navigateOpts) {
|
|
1981
|
-
if (navigateOpts === void 0) {
|
|
1982
|
-
navigateOpts = router.location;
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
|
-
const next = router.buildNext(navigateOpts);
|
|
1986
|
-
const matches = router.matchRoutes(next.pathname, {
|
|
1987
|
-
strictParseParams: true
|
|
1988
|
-
});
|
|
1989
|
-
await router.loadMatches(matches);
|
|
1990
|
-
return matches;
|
|
1991
|
-
},
|
|
1992
|
-
preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
|
|
1993
|
-
var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
|
|
1994
|
-
|
|
1995
|
-
if (navigateOpts === void 0) {
|
|
1996
|
-
navigateOpts = router.location;
|
|
1997
|
-
}
|
|
1998
|
-
|
|
1999
|
-
const next = router.buildNext(navigateOpts);
|
|
2000
|
-
const matches = router.matchRoutes(next.pathname, {
|
|
2001
|
-
strictParseParams: true
|
|
2002
|
-
});
|
|
2003
|
-
await router.loadMatches(matches, {
|
|
2004
|
-
preload: true,
|
|
2005
|
-
maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
|
|
2006
|
-
gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
|
|
2007
|
-
});
|
|
2008
|
-
return matches;
|
|
2009
|
-
},
|
|
2010
|
-
matchRoutes: (pathname, opts) => {
|
|
2011
|
-
var _router$state$pending3, _router$state$pending4;
|
|
2012
|
-
|
|
2013
|
-
router.cleanMatchCache();
|
|
2014
|
-
const matches = [];
|
|
2015
|
-
|
|
2016
|
-
if (!router.routeTree) {
|
|
2017
|
-
return matches;
|
|
809
|
+
str && (str += '&');
|
|
810
|
+
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
|
|
2018
811
|
}
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
return (pfx || '') + str;
|
|
815
|
+
}
|
|
816
|
+
function toValue(mix) {
|
|
817
|
+
if (!mix) return '';
|
|
818
|
+
var str = decodeURIComponent(mix);
|
|
819
|
+
if (str === 'false') return false;
|
|
820
|
+
if (str === 'true') return true;
|
|
821
|
+
return +str * 0 === 0 && +str + '' === str ? +str : str;
|
|
822
|
+
}
|
|
823
|
+
function decode(str) {
|
|
824
|
+
var tmp,
|
|
825
|
+
k,
|
|
826
|
+
out = {},
|
|
827
|
+
arr = str.split('&');
|
|
828
|
+
while (tmp = arr.shift()) {
|
|
829
|
+
tmp = tmp.split('=');
|
|
830
|
+
k = tmp.shift();
|
|
831
|
+
if (out[k] !== void 0) {
|
|
832
|
+
out[k] = [].concat(out[k], toValue(tmp.shift()));
|
|
833
|
+
} else {
|
|
834
|
+
out[k] = toValue(tmp.shift());
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return out;
|
|
838
|
+
}
|
|
2019
839
|
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
let foundRoutes = [];
|
|
2029
|
-
|
|
2030
|
-
const findMatchInRoutes = (parentRoutes, routes) => {
|
|
2031
|
-
routes.some(route => {
|
|
2032
|
-
var _route$childRoutes, _route$childRoutes2, _route$options$caseSe;
|
|
2033
|
-
|
|
2034
|
-
if (!route.routePath && (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length) {
|
|
2035
|
-
return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
|
-
const fuzzy = !!(route.routePath !== '/' || (_route$childRoutes2 = route.childRoutes) != null && _route$childRoutes2.length);
|
|
2039
|
-
const matchParams = matchPathname(pathname, {
|
|
2040
|
-
to: route.fullPath,
|
|
2041
|
-
fuzzy,
|
|
2042
|
-
caseSensitive: (_route$options$caseSe = route.options.caseSensitive) != null ? _route$options$caseSe : router.options.caseSensitive
|
|
2043
|
-
});
|
|
2044
|
-
|
|
2045
|
-
if (matchParams) {
|
|
2046
|
-
let parsedParams;
|
|
2047
|
-
|
|
2048
|
-
try {
|
|
2049
|
-
var _route$options$parseP;
|
|
2050
|
-
|
|
2051
|
-
parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
|
|
2052
|
-
} catch (err) {
|
|
2053
|
-
if (opts != null && opts.strictParseParams) {
|
|
2054
|
-
throw err;
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
|
-
params = _extends({}, params, parsedParams);
|
|
2059
|
-
}
|
|
2060
|
-
|
|
2061
|
-
if (!!matchParams) {
|
|
2062
|
-
foundRoutes = [...parentRoutes, route];
|
|
2063
|
-
}
|
|
2064
|
-
|
|
2065
|
-
return !!foundRoutes.length;
|
|
2066
|
-
});
|
|
2067
|
-
return !!foundRoutes.length;
|
|
2068
|
-
};
|
|
2069
|
-
|
|
2070
|
-
findMatchInRoutes([], filteredRoutes);
|
|
2071
|
-
|
|
2072
|
-
if (!foundRoutes.length) {
|
|
2073
|
-
return;
|
|
2074
|
-
}
|
|
2075
|
-
|
|
2076
|
-
foundRoutes.forEach(foundRoute => {
|
|
2077
|
-
var _router$matchCache$ma;
|
|
2078
|
-
|
|
2079
|
-
const interpolatedPath = interpolatePath(foundRoute.routePath, params);
|
|
2080
|
-
const matchId = interpolatePath(foundRoute.routeId, params, true);
|
|
2081
|
-
const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || createRouteMatch(router, foundRoute, {
|
|
2082
|
-
parentMatch,
|
|
2083
|
-
matchId,
|
|
2084
|
-
params,
|
|
2085
|
-
pathname: joinPaths([pathname, interpolatedPath])
|
|
2086
|
-
});
|
|
2087
|
-
matches.push(match);
|
|
2088
|
-
});
|
|
2089
|
-
const foundRoute = last(foundRoutes);
|
|
2090
|
-
|
|
2091
|
-
if ((_foundRoute$childRout = foundRoute.childRoutes) != null && _foundRoute$childRout.length) {
|
|
2092
|
-
recurse(foundRoute.childRoutes);
|
|
2093
|
-
}
|
|
2094
|
-
};
|
|
2095
|
-
|
|
2096
|
-
recurse([router.routeTree]);
|
|
2097
|
-
cascadeLoaderData(matches);
|
|
2098
|
-
return matches;
|
|
2099
|
-
},
|
|
2100
|
-
loadMatches: async (resolvedMatches, loaderOpts) => {
|
|
2101
|
-
const matchPromises = resolvedMatches.map(async match => {
|
|
2102
|
-
// Validate the match (loads search params etc)
|
|
2103
|
-
match.__.validate();
|
|
2104
|
-
|
|
2105
|
-
match.load(loaderOpts);
|
|
2106
|
-
const search = match.search;
|
|
2107
|
-
|
|
2108
|
-
if (search.__data && search.__data.matchId !== match.matchId) {
|
|
2109
|
-
return;
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
if (match.__.loadPromise) {
|
|
2113
|
-
// Wait for the first sign of activity from the match
|
|
2114
|
-
await match.__.loadPromise;
|
|
2115
|
-
}
|
|
2116
|
-
});
|
|
2117
|
-
router.notify();
|
|
2118
|
-
await Promise.all(matchPromises);
|
|
2119
|
-
},
|
|
2120
|
-
loadMatchData: async routeMatch => {
|
|
2121
|
-
if (isServer || !router.options.useServerData) {
|
|
2122
|
-
var _await$routeMatch$opt;
|
|
2123
|
-
|
|
2124
|
-
return (_await$routeMatch$opt = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
|
|
2125
|
-
// parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
|
|
2126
|
-
params: routeMatch.params,
|
|
2127
|
-
search: routeMatch.routeSearch,
|
|
2128
|
-
signal: routeMatch.__.abortController.signal
|
|
2129
|
-
}))) != null ? _await$routeMatch$opt : {};
|
|
2130
|
-
} else {
|
|
2131
|
-
const next = router.buildNext({
|
|
2132
|
-
to: '.',
|
|
2133
|
-
search: d => _extends({}, d != null ? d : {}, {
|
|
2134
|
-
__data: {
|
|
2135
|
-
matchId: routeMatch.matchId
|
|
2136
|
-
}
|
|
2137
|
-
})
|
|
2138
|
-
});
|
|
2139
|
-
const res = await fetch(next.href, {
|
|
2140
|
-
method: 'GET' // signal: routeMatch.__.abortController.signal,
|
|
2141
|
-
|
|
2142
|
-
});
|
|
840
|
+
const defaultParseSearch = parseSearchWith(JSON.parse);
|
|
841
|
+
const defaultStringifySearch = stringifySearchWith(JSON.stringify, JSON.parse);
|
|
842
|
+
function parseSearchWith(parser) {
|
|
843
|
+
return searchStr => {
|
|
844
|
+
if (searchStr.substring(0, 1) === '?') {
|
|
845
|
+
searchStr = searchStr.substring(1);
|
|
846
|
+
}
|
|
847
|
+
let query = decode(searchStr);
|
|
2143
848
|
|
|
2144
|
-
|
|
2145
|
-
|
|
849
|
+
// Try to parse any query params that might be json
|
|
850
|
+
for (let key in query) {
|
|
851
|
+
const value = query[key];
|
|
852
|
+
if (typeof value === 'string') {
|
|
853
|
+
try {
|
|
854
|
+
query[key] = parser(value);
|
|
855
|
+
} catch (err) {
|
|
856
|
+
//
|
|
2146
857
|
}
|
|
2147
|
-
|
|
2148
|
-
throw new Error('Failed to fetch match data');
|
|
2149
858
|
}
|
|
2150
|
-
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
},
|
|
2162
|
-
reload: () => router.__.navigate({
|
|
2163
|
-
fromCurrent: true,
|
|
2164
|
-
replace: true,
|
|
2165
|
-
search: true
|
|
2166
|
-
}),
|
|
2167
|
-
resolvePath: (from, path) => {
|
|
2168
|
-
return resolvePath(router.basepath, from, cleanPath(path));
|
|
2169
|
-
},
|
|
2170
|
-
matchRoute: (location, opts) => {
|
|
2171
|
-
var _location$from;
|
|
2172
|
-
|
|
2173
|
-
// const location = router.buildNext(opts)
|
|
2174
|
-
location = _extends({}, location, {
|
|
2175
|
-
to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
|
|
2176
|
-
});
|
|
2177
|
-
const next = router.buildNext(location);
|
|
2178
|
-
|
|
2179
|
-
if (opts != null && opts.pending) {
|
|
2180
|
-
var _router$state$pending7;
|
|
2181
|
-
|
|
2182
|
-
if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
|
|
2183
|
-
return false;
|
|
2184
|
-
}
|
|
2185
|
-
|
|
2186
|
-
return !!matchPathname(router.state.pending.location.pathname, _extends({}, opts, {
|
|
2187
|
-
to: next.pathname
|
|
2188
|
-
}));
|
|
859
|
+
}
|
|
860
|
+
return query;
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
function stringifySearchWith(stringify, parser) {
|
|
864
|
+
function stringifyValue(val) {
|
|
865
|
+
if (typeof val === 'object' && val !== null) {
|
|
866
|
+
try {
|
|
867
|
+
return stringify(val);
|
|
868
|
+
} catch (err) {
|
|
869
|
+
// silent
|
|
2189
870
|
}
|
|
2190
|
-
|
|
2191
|
-
return !!matchPathname(router.state.location.pathname, _extends({}, opts, {
|
|
2192
|
-
to: next.pathname
|
|
2193
|
-
}));
|
|
2194
|
-
},
|
|
2195
|
-
navigate: async _ref7 => {
|
|
2196
|
-
let {
|
|
2197
|
-
from,
|
|
2198
|
-
to = '.',
|
|
2199
|
-
search,
|
|
2200
|
-
hash,
|
|
2201
|
-
replace,
|
|
2202
|
-
params
|
|
2203
|
-
} = _ref7;
|
|
2204
|
-
// If this link simply reloads the current route,
|
|
2205
|
-
// make sure it has a new key so it will trigger a data refresh
|
|
2206
|
-
// If this `to` is a valid external URL, return
|
|
2207
|
-
// null for LinkUtils
|
|
2208
|
-
const toString = String(to);
|
|
2209
|
-
const fromString = String(from);
|
|
2210
|
-
let isExternal;
|
|
2211
|
-
|
|
871
|
+
} else if (typeof val === 'string' && typeof parser === 'function') {
|
|
2212
872
|
try {
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
873
|
+
// Check if it's a valid parseable string.
|
|
874
|
+
// If it is, then stringify it again.
|
|
875
|
+
parser(val);
|
|
876
|
+
return stringify(val);
|
|
877
|
+
} catch (err) {
|
|
878
|
+
// silent
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
return val;
|
|
882
|
+
}
|
|
883
|
+
return search => {
|
|
884
|
+
search = {
|
|
885
|
+
...search
|
|
886
|
+
};
|
|
887
|
+
if (search) {
|
|
888
|
+
Object.keys(search).forEach(key => {
|
|
889
|
+
const val = search[key];
|
|
890
|
+
if (typeof val === 'undefined' || val === undefined) {
|
|
891
|
+
delete search[key];
|
|
892
|
+
} else {
|
|
893
|
+
search[key] = stringifyValue(val);
|
|
894
|
+
}
|
|
2225
895
|
});
|
|
2226
|
-
}
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
from,
|
|
2232
|
-
to = '.',
|
|
2233
|
-
search,
|
|
2234
|
-
params,
|
|
2235
|
-
hash,
|
|
2236
|
-
target,
|
|
2237
|
-
replace,
|
|
2238
|
-
activeOptions,
|
|
2239
|
-
preload,
|
|
2240
|
-
preloadMaxAge: userPreloadMaxAge,
|
|
2241
|
-
preloadGcMaxAge: userPreloadGcMaxAge,
|
|
2242
|
-
preloadDelay: userPreloadDelay,
|
|
2243
|
-
disabled
|
|
2244
|
-
} = _ref8;
|
|
2245
|
-
|
|
2246
|
-
// If this link simply reloads the current route,
|
|
2247
|
-
// make sure it has a new key so it will trigger a data refresh
|
|
2248
|
-
// If this `to` is a valid external URL, return
|
|
2249
|
-
// null for LinkUtils
|
|
2250
|
-
try {
|
|
2251
|
-
new URL("" + to);
|
|
2252
|
-
return {
|
|
2253
|
-
type: 'external',
|
|
2254
|
-
href: to
|
|
2255
|
-
};
|
|
2256
|
-
} catch (e) {}
|
|
2257
|
-
|
|
2258
|
-
const nextOpts = {
|
|
2259
|
-
from,
|
|
2260
|
-
to,
|
|
2261
|
-
search,
|
|
2262
|
-
params,
|
|
2263
|
-
hash,
|
|
2264
|
-
replace
|
|
2265
|
-
};
|
|
2266
|
-
const next = router.buildNext(nextOpts);
|
|
2267
|
-
preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
|
|
2268
|
-
const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
|
|
2269
|
-
|
|
2270
|
-
const pathIsEqual = router.state.location.pathname === next.pathname;
|
|
2271
|
-
const currentPathSplit = router.state.location.pathname.split('/');
|
|
2272
|
-
const nextPathSplit = next.pathname.split('/');
|
|
2273
|
-
const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
|
|
2274
|
-
const hashIsEqual = router.state.location.hash === next.hash; // Combine the matches based on user options
|
|
2275
|
-
|
|
2276
|
-
const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
|
|
2277
|
-
const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true; // The final "active" test
|
|
2278
|
-
|
|
2279
|
-
const isActive = pathTest && hashTest; // The click handler
|
|
2280
|
-
|
|
2281
|
-
const handleClick = e => {
|
|
2282
|
-
if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
|
|
2283
|
-
e.preventDefault();
|
|
896
|
+
}
|
|
897
|
+
const searchStr = encode(search).toString();
|
|
898
|
+
return searchStr ? `?${searchStr}` : '';
|
|
899
|
+
};
|
|
900
|
+
}
|
|
2284
901
|
|
|
2285
|
-
|
|
2286
|
-
router.invalidateRoute(nextOpts);
|
|
2287
|
-
} // All is well? Navigate!)
|
|
902
|
+
//
|
|
2288
903
|
|
|
904
|
+
//
|
|
2289
905
|
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
906
|
+
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
907
|
+
class Router {
|
|
908
|
+
// dehydratedData?: TDehydrated
|
|
909
|
+
// resetNextScroll = false
|
|
910
|
+
// tempLocationKey = `${Math.round(Math.random() * 10000000)}`
|
|
911
|
+
constructor(options) {
|
|
912
|
+
this.options = {
|
|
913
|
+
defaultPreloadDelay: 50,
|
|
914
|
+
context: undefined,
|
|
915
|
+
...options,
|
|
916
|
+
stringifySearch: options?.stringifySearch ?? defaultStringifySearch,
|
|
917
|
+
parseSearch: options?.parseSearch ?? defaultParseSearch
|
|
918
|
+
};
|
|
919
|
+
this.routeTree = this.options.routeTree;
|
|
920
|
+
}
|
|
921
|
+
subscribers = new Set();
|
|
922
|
+
subscribe = (eventType, fn) => {
|
|
923
|
+
const listener = {
|
|
924
|
+
eventType,
|
|
925
|
+
fn
|
|
926
|
+
};
|
|
927
|
+
this.subscribers.add(listener);
|
|
928
|
+
return () => {
|
|
929
|
+
this.subscribers.delete(listener);
|
|
930
|
+
};
|
|
931
|
+
};
|
|
932
|
+
emit = routerEvent => {
|
|
933
|
+
this.subscribers.forEach(listener => {
|
|
934
|
+
if (listener.eventType === routerEvent.type) {
|
|
935
|
+
listener.fn(routerEvent);
|
|
936
|
+
}
|
|
937
|
+
});
|
|
938
|
+
};
|
|
2293
939
|
|
|
940
|
+
// dehydrate = (): DehydratedRouter => {
|
|
941
|
+
// return {
|
|
942
|
+
// state: {
|
|
943
|
+
// dehydratedMatches: state.matches.map((d) =>
|
|
944
|
+
// pick(d, ['fetchedAt', 'invalid', 'id', 'status', 'updatedAt']),
|
|
945
|
+
// ),
|
|
946
|
+
// },
|
|
947
|
+
// }
|
|
948
|
+
// }
|
|
2294
949
|
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
950
|
+
// hydrate = async (__do_not_use_server_ctx?: HydrationCtx) => {
|
|
951
|
+
// let _ctx = __do_not_use_server_ctx
|
|
952
|
+
// // Client hydrates from window
|
|
953
|
+
// if (typeof document !== 'undefined') {
|
|
954
|
+
// _ctx = window.__TSR_DEHYDRATED__
|
|
955
|
+
// }
|
|
956
|
+
|
|
957
|
+
// invariant(
|
|
958
|
+
// _ctx,
|
|
959
|
+
// 'Expected to find a __TSR_DEHYDRATED__ property on window... but we did not. Did you forget to render <DehydrateRouter /> in your app?',
|
|
960
|
+
// )
|
|
961
|
+
|
|
962
|
+
// const ctx = _ctx
|
|
963
|
+
// this.dehydratedData = ctx.payload as any
|
|
964
|
+
// this.options.hydrate?.(ctx.payload as any)
|
|
965
|
+
// const dehydratedState = ctx.router.state
|
|
966
|
+
|
|
967
|
+
// let matches = this.matchRoutes(
|
|
968
|
+
// state.location.pathname,
|
|
969
|
+
// state.location.search,
|
|
970
|
+
// ).map((match) => {
|
|
971
|
+
// const dehydratedMatch = dehydratedState.dehydratedMatches.find(
|
|
972
|
+
// (d) => d.id === match.id,
|
|
973
|
+
// )
|
|
974
|
+
|
|
975
|
+
// invariant(
|
|
976
|
+
// dehydratedMatch,
|
|
977
|
+
// `Could not find a client-side match for dehydrated match with id: ${match.id}!`,
|
|
978
|
+
// )
|
|
979
|
+
|
|
980
|
+
// if (dehydratedMatch) {
|
|
981
|
+
// return {
|
|
982
|
+
// ...match,
|
|
983
|
+
// ...dehydratedMatch,
|
|
984
|
+
// }
|
|
985
|
+
// }
|
|
986
|
+
// return match
|
|
987
|
+
// })
|
|
988
|
+
|
|
989
|
+
// this.setState((s) => {
|
|
990
|
+
// return {
|
|
991
|
+
// ...s,
|
|
992
|
+
// matches: dehydratedState.dehydratedMatches as any,
|
|
993
|
+
// }
|
|
994
|
+
// })
|
|
995
|
+
// }
|
|
2303
996
|
|
|
2304
|
-
|
|
2305
|
-
|
|
997
|
+
// resolveMatchPromise = (matchId: string, key: string, value: any) => {
|
|
998
|
+
// state.matches
|
|
999
|
+
// .find((d) => d.id === matchId)
|
|
1000
|
+
// ?.__promisesByKey[key]?.resolve(value)
|
|
1001
|
+
// }
|
|
2306
1002
|
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
1003
|
+
// setRouteMatch = (
|
|
1004
|
+
// id: string,
|
|
1005
|
+
// pending: boolean,
|
|
1006
|
+
// updater: NonNullableUpdater<RouteMatch<TRouteTree>>,
|
|
1007
|
+
// ) => {
|
|
1008
|
+
// const key = pending ? 'pendingMatches' : 'matches'
|
|
1009
|
+
|
|
1010
|
+
// this.setState((prev) => {
|
|
1011
|
+
// return {
|
|
1012
|
+
// ...prev,
|
|
1013
|
+
// [key]: prev[key].map((d) => {
|
|
1014
|
+
// if (d.id === id) {
|
|
1015
|
+
// return functionalUpdate(updater, d)
|
|
1016
|
+
// }
|
|
1017
|
+
|
|
1018
|
+
// return d
|
|
1019
|
+
// }),
|
|
1020
|
+
// }
|
|
1021
|
+
// })
|
|
1022
|
+
// }
|
|
2311
1023
|
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
}
|
|
2320
|
-
};
|
|
1024
|
+
// setPendingRouteMatch = (
|
|
1025
|
+
// id: string,
|
|
1026
|
+
// updater: NonNullableUpdater<RouteMatch<TRouteTree>>,
|
|
1027
|
+
// ) => {
|
|
1028
|
+
// this.setRouteMatch(id, true, updater)
|
|
1029
|
+
// }
|
|
1030
|
+
}
|
|
2321
1031
|
|
|
2322
|
-
|
|
2323
|
-
|
|
1032
|
+
// A function that takes an import() argument which is a function and returns a new function that will
|
|
1033
|
+
// proxy arguments from the caller to the imported function, retaining all type
|
|
1034
|
+
// information along the way
|
|
1035
|
+
function lazyFn(fn, key) {
|
|
1036
|
+
return async (...args) => {
|
|
1037
|
+
const imported = await fn();
|
|
1038
|
+
return imported[key || 'default'](...args);
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
2324
1041
|
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
1042
|
+
const routerContext = /*#__PURE__*/React.createContext(null);
|
|
1043
|
+
if (typeof document !== 'undefined') {
|
|
1044
|
+
window.__TSR_ROUTER_CONTEXT__ = routerContext;
|
|
1045
|
+
}
|
|
1046
|
+
const preloadWarning = 'Error preloading route! ☝️';
|
|
1047
|
+
function isCtrlEvent(e) {
|
|
1048
|
+
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
1049
|
+
}
|
|
1050
|
+
class SearchParamError extends Error {}
|
|
1051
|
+
class PathParamError extends Error {}
|
|
1052
|
+
function getInitialRouterState(location) {
|
|
1053
|
+
return {
|
|
1054
|
+
status: 'idle',
|
|
1055
|
+
resolvedLocation: location,
|
|
1056
|
+
location,
|
|
1057
|
+
matches: [],
|
|
1058
|
+
pendingMatches: [],
|
|
1059
|
+
lastUpdated: Date.now()
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
function RouterProvider({
|
|
1063
|
+
router,
|
|
1064
|
+
...rest
|
|
1065
|
+
}) {
|
|
1066
|
+
const options = {
|
|
1067
|
+
...router.options,
|
|
1068
|
+
...rest,
|
|
1069
|
+
context: {
|
|
1070
|
+
...router.options.context,
|
|
1071
|
+
...rest?.context
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
const history = React.useState(() => options.history ?? createBrowserHistory())[0];
|
|
1075
|
+
const tempLocationKeyRef = React.useRef(`${Math.round(Math.random() * 10000000)}`);
|
|
1076
|
+
const resetNextScrollRef = React.useRef(true);
|
|
1077
|
+
const navigateTimeoutRef = React.useRef(null);
|
|
1078
|
+
const latestLoadPromiseRef = React.useRef(Promise.resolve());
|
|
1079
|
+
const checkLatest = promise => {
|
|
1080
|
+
return latestLoadPromiseRef.current !== promise ? latestLoadPromiseRef.current : undefined;
|
|
1081
|
+
};
|
|
1082
|
+
const parseLocation = useStableCallback(previousLocation => {
|
|
1083
|
+
const parse = ({
|
|
1084
|
+
pathname,
|
|
1085
|
+
search,
|
|
1086
|
+
hash,
|
|
1087
|
+
state
|
|
1088
|
+
}) => {
|
|
1089
|
+
const parsedSearch = options.parseSearch(search);
|
|
1090
|
+
return {
|
|
1091
|
+
pathname: pathname,
|
|
1092
|
+
searchStr: search,
|
|
1093
|
+
search: replaceEqualDeep(previousLocation?.search, parsedSearch),
|
|
1094
|
+
hash: hash.split('#').reverse()[0] ?? '',
|
|
1095
|
+
href: `${pathname}${search}${hash}`,
|
|
1096
|
+
state: replaceEqualDeep(previousLocation?.state, state)
|
|
2329
1097
|
};
|
|
2330
|
-
|
|
1098
|
+
};
|
|
1099
|
+
const location = parse(history.location);
|
|
1100
|
+
let {
|
|
1101
|
+
__tempLocation,
|
|
1102
|
+
__tempKey
|
|
1103
|
+
} = location.state;
|
|
1104
|
+
if (__tempLocation && (!__tempKey || __tempKey === tempLocationKeyRef.current)) {
|
|
1105
|
+
// Sync up the location keys
|
|
1106
|
+
const parsedTempLocation = parse(__tempLocation);
|
|
1107
|
+
parsedTempLocation.state.key = location.state.key;
|
|
1108
|
+
delete parsedTempLocation.state.__tempLocation;
|
|
2331
1109
|
return {
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
handleFocus,
|
|
2335
|
-
handleClick,
|
|
2336
|
-
handleEnter,
|
|
2337
|
-
handleLeave,
|
|
2338
|
-
isActive,
|
|
2339
|
-
disabled
|
|
1110
|
+
...parsedTempLocation,
|
|
1111
|
+
maskedLocation: location
|
|
2340
1112
|
};
|
|
2341
|
-
}
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
1113
|
+
}
|
|
1114
|
+
return location;
|
|
1115
|
+
});
|
|
1116
|
+
const latestLocationRef = React.useRef(parseLocation());
|
|
1117
|
+
const [preState, setState] = React.useState(() => getInitialRouterState(latestLocationRef.current));
|
|
1118
|
+
const [isTransitioning, startReactTransition] = React.useTransition();
|
|
1119
|
+
const pendingMatchesRef = React.useRef([]);
|
|
1120
|
+
const state = React.useMemo(() => ({
|
|
1121
|
+
...preState,
|
|
1122
|
+
status: isTransitioning ? 'pending' : 'idle',
|
|
1123
|
+
location: isTransitioning ? latestLocationRef.current : preState.location,
|
|
1124
|
+
pendingMatches: pendingMatchesRef.current
|
|
1125
|
+
}), [preState, isTransitioning]);
|
|
1126
|
+
React.useLayoutEffect(() => {
|
|
1127
|
+
if (!isTransitioning && state.resolvedLocation !== state.location) {
|
|
1128
|
+
router.emit({
|
|
1129
|
+
type: 'onResolved',
|
|
1130
|
+
fromLocation: state.resolvedLocation,
|
|
1131
|
+
toLocation: state.location,
|
|
1132
|
+
pathChanged: state.location.href !== state.resolvedLocation?.href
|
|
1133
|
+
});
|
|
1134
|
+
pendingMatchesRef.current = [];
|
|
1135
|
+
setState(s => ({
|
|
1136
|
+
...s,
|
|
1137
|
+
resolvedLocation: s.location
|
|
2362
1138
|
}));
|
|
2363
|
-
}
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
const routes = recurseRoutes([rootRouteConfig]);
|
|
2387
|
-
return routes[0];
|
|
2388
|
-
},
|
|
2389
|
-
parseLocation: (location, previousLocation) => {
|
|
2390
|
-
var _location$hash$split$;
|
|
2391
|
-
|
|
2392
|
-
const parsedSearch = router.options.parseSearch(location.search);
|
|
2393
|
-
return {
|
|
2394
|
-
pathname: location.pathname,
|
|
2395
|
-
searchStr: location.search,
|
|
2396
|
-
search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
|
|
2397
|
-
hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
|
|
2398
|
-
href: "" + location.pathname + location.search + location.hash,
|
|
2399
|
-
state: location.state,
|
|
2400
|
-
key: location.key
|
|
2401
|
-
};
|
|
2402
|
-
},
|
|
2403
|
-
navigate: location => {
|
|
2404
|
-
const next = router.buildNext(location);
|
|
2405
|
-
return router.__.commitLocation(next, location.replace);
|
|
2406
|
-
},
|
|
2407
|
-
buildLocation: function buildLocation(dest) {
|
|
2408
|
-
var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
|
|
2409
|
-
|
|
2410
|
-
if (dest === void 0) {
|
|
2411
|
-
dest = {};
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
const basepath = `/${trimPath(options.basepath ?? '') ?? ''}`;
|
|
1142
|
+
const resolvePathWithBase = useStableCallback((from, path) => {
|
|
1143
|
+
return resolvePath(basepath, from, cleanPath(path));
|
|
1144
|
+
});
|
|
1145
|
+
const [routesById, routesByPath] = React.useMemo(() => {
|
|
1146
|
+
const routesById = {};
|
|
1147
|
+
const routesByPath = {};
|
|
1148
|
+
const recurseRoutes = routes => {
|
|
1149
|
+
routes.forEach((route, i) => {
|
|
1150
|
+
route.init({
|
|
1151
|
+
originalIndex: i
|
|
1152
|
+
});
|
|
1153
|
+
const existingRoute = routesById[route.id];
|
|
1154
|
+
invariant(!existingRoute, `Duplicate routes found with id: ${String(route.id)}`);
|
|
1155
|
+
routesById[route.id] = route;
|
|
1156
|
+
if (!route.isRoot && route.path) {
|
|
1157
|
+
const trimmedFullPath = trimPathRight(route.fullPath);
|
|
1158
|
+
if (!routesByPath[trimmedFullPath] || route.fullPath.endsWith('/')) {
|
|
1159
|
+
routesByPath[trimmedFullPath] = route;
|
|
1160
|
+
}
|
|
2412
1161
|
}
|
|
1162
|
+
const children = route.children;
|
|
1163
|
+
if (children?.length) {
|
|
1164
|
+
recurseRoutes(children);
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
};
|
|
1168
|
+
recurseRoutes([router.routeTree]);
|
|
1169
|
+
return [routesById, routesByPath];
|
|
1170
|
+
}, []);
|
|
1171
|
+
const looseRoutesById = routesById;
|
|
1172
|
+
const flatRoutes = React.useMemo(() => Object.values(routesByPath).map((d, i) => {
|
|
1173
|
+
const trimmed = trimPath(d.fullPath);
|
|
1174
|
+
const parsed = parsePathname(trimmed);
|
|
1175
|
+
while (parsed.length > 1 && parsed[0]?.value === '/') {
|
|
1176
|
+
parsed.shift();
|
|
1177
|
+
}
|
|
1178
|
+
const score = parsed.map(d => {
|
|
1179
|
+
if (d.type === 'param') {
|
|
1180
|
+
return 0.5;
|
|
1181
|
+
}
|
|
1182
|
+
if (d.type === 'wildcard') {
|
|
1183
|
+
return 0.25;
|
|
1184
|
+
}
|
|
1185
|
+
return 1;
|
|
1186
|
+
});
|
|
1187
|
+
return {
|
|
1188
|
+
child: d,
|
|
1189
|
+
trimmed,
|
|
1190
|
+
parsed,
|
|
1191
|
+
index: i,
|
|
1192
|
+
score
|
|
1193
|
+
};
|
|
1194
|
+
}).sort((a, b) => {
|
|
1195
|
+
let isIndex = a.trimmed === '/' ? 1 : b.trimmed === '/' ? -1 : 0;
|
|
1196
|
+
if (isIndex !== 0) return isIndex;
|
|
1197
|
+
const length = Math.min(a.score.length, b.score.length);
|
|
1198
|
+
|
|
1199
|
+
// Sort by length of score
|
|
1200
|
+
if (a.score.length !== b.score.length) {
|
|
1201
|
+
return b.score.length - a.score.length;
|
|
1202
|
+
}
|
|
2413
1203
|
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
1204
|
+
// Sort by min available score
|
|
1205
|
+
for (let i = 0; i < length; i++) {
|
|
1206
|
+
if (a.score[i] !== b.score[i]) {
|
|
1207
|
+
return b.score[i] - a.score[i];
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
2417
1210
|
|
|
2418
|
-
|
|
1211
|
+
// Sort by min available parsed value
|
|
1212
|
+
for (let i = 0; i < length; i++) {
|
|
1213
|
+
if (a.parsed[i].value !== b.parsed[i].value) {
|
|
1214
|
+
return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
2419
1217
|
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
1218
|
+
// Sort by length of trimmed full path
|
|
1219
|
+
if (a.trimmed !== b.trimmed) {
|
|
1220
|
+
return a.trimmed > b.trimmed ? 1 : -1;
|
|
1221
|
+
}
|
|
2424
1222
|
|
|
2425
|
-
|
|
1223
|
+
// Sort by original index
|
|
1224
|
+
return a.index - b.index;
|
|
1225
|
+
}).map((d, i) => {
|
|
1226
|
+
d.child.rank = i;
|
|
1227
|
+
return d.child;
|
|
1228
|
+
}), [routesByPath]);
|
|
1229
|
+
const matchRoutes = useStableCallback((pathname, locationSearch, opts) => {
|
|
1230
|
+
let routeParams = {};
|
|
1231
|
+
let foundRoute = flatRoutes.find(route => {
|
|
1232
|
+
const matchedParams = matchPathname(basepath, trimPathRight(pathname), {
|
|
1233
|
+
to: route.fullPath,
|
|
1234
|
+
caseSensitive: route.options.caseSensitive ?? options.caseSensitive,
|
|
1235
|
+
fuzzy: false
|
|
1236
|
+
});
|
|
1237
|
+
if (matchedParams) {
|
|
1238
|
+
routeParams = matchedParams;
|
|
1239
|
+
return true;
|
|
1240
|
+
}
|
|
1241
|
+
return false;
|
|
1242
|
+
});
|
|
1243
|
+
let routeCursor = foundRoute || routesById['__root__'];
|
|
1244
|
+
let matchedRoutes = [routeCursor];
|
|
1245
|
+
// let includingLayouts = true
|
|
1246
|
+
while (routeCursor?.parentRoute) {
|
|
1247
|
+
routeCursor = routeCursor.parentRoute;
|
|
1248
|
+
if (routeCursor) matchedRoutes.unshift(routeCursor);
|
|
1249
|
+
}
|
|
2426
1250
|
|
|
2427
|
-
|
|
1251
|
+
// Existing matches are matches that are already loaded along with
|
|
1252
|
+
// pending matches that are still loading
|
|
2428
1253
|
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
1254
|
+
const parseErrors = matchedRoutes.map(route => {
|
|
1255
|
+
let parsedParamsError;
|
|
1256
|
+
if (route.options.parseParams) {
|
|
1257
|
+
try {
|
|
1258
|
+
const parsedParams = route.options.parseParams(routeParams);
|
|
1259
|
+
// Add the parsed params to the accumulated params bag
|
|
1260
|
+
Object.assign(routeParams, parsedParams);
|
|
1261
|
+
} catch (err) {
|
|
1262
|
+
parsedParamsError = new PathParamError(err.message, {
|
|
1263
|
+
cause: err
|
|
2432
1264
|
});
|
|
1265
|
+
if (opts?.throwOnError) {
|
|
1266
|
+
throw parsedParamsError;
|
|
1267
|
+
}
|
|
1268
|
+
return parsedParamsError;
|
|
2433
1269
|
}
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
const searchStr = router.options.stringifySearch(search);
|
|
2447
|
-
let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
|
|
2448
|
-
hash = hash ? "#" + hash : '';
|
|
1270
|
+
}
|
|
1271
|
+
return;
|
|
1272
|
+
});
|
|
1273
|
+
const matches = matchedRoutes.map((route, index) => {
|
|
1274
|
+
const interpolatedPath = interpolatePath(route.path, routeParams);
|
|
1275
|
+
const matchId = interpolatePath(route.id, routeParams, true);
|
|
1276
|
+
|
|
1277
|
+
// Waste not, want not. If we already have a match for this route,
|
|
1278
|
+
// reuse it. This is important for layout routes, which might stick
|
|
1279
|
+
// around between navigation actions that only change leaf routes.
|
|
1280
|
+
const existingMatch = getRouteMatch(state, matchId);
|
|
1281
|
+
if (existingMatch) {
|
|
2449
1282
|
return {
|
|
2450
|
-
|
|
2451
|
-
search,
|
|
2452
|
-
searchStr,
|
|
2453
|
-
state: router.location.state,
|
|
2454
|
-
hash,
|
|
2455
|
-
href: "" + pathname + searchStr + hash,
|
|
2456
|
-
key: dest.key
|
|
1283
|
+
...existingMatch
|
|
2457
1284
|
};
|
|
2458
|
-
}
|
|
2459
|
-
commitLocation: (next, replace) => {
|
|
2460
|
-
const id = '' + Date.now() + Math.random();
|
|
2461
|
-
if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
|
|
2462
|
-
let nextAction = 'replace';
|
|
2463
|
-
|
|
2464
|
-
if (!replace) {
|
|
2465
|
-
nextAction = 'push';
|
|
2466
|
-
}
|
|
2467
|
-
|
|
2468
|
-
const isSameUrl = router.__.parseLocation(history.location).href === next.href;
|
|
1285
|
+
}
|
|
2469
1286
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
1287
|
+
// Create a fresh route match
|
|
1288
|
+
const hasLoaders = !!(route.options.loader || componentTypes.some(d => route.options[d]?.preload));
|
|
1289
|
+
const routeMatch = {
|
|
1290
|
+
id: matchId,
|
|
1291
|
+
routeId: route.id,
|
|
1292
|
+
params: routeParams,
|
|
1293
|
+
pathname: joinPaths([basepath, interpolatedPath]),
|
|
1294
|
+
updatedAt: Date.now(),
|
|
1295
|
+
routeSearch: {},
|
|
1296
|
+
search: {},
|
|
1297
|
+
status: hasLoaders ? 'pending' : 'success',
|
|
1298
|
+
isFetching: false,
|
|
1299
|
+
invalid: false,
|
|
1300
|
+
error: undefined,
|
|
1301
|
+
paramsError: parseErrors[index],
|
|
1302
|
+
searchError: undefined,
|
|
1303
|
+
loadPromise: Promise.resolve(),
|
|
1304
|
+
context: undefined,
|
|
1305
|
+
abortController: new AbortController(),
|
|
1306
|
+
shouldReloadDeps: undefined,
|
|
1307
|
+
fetchedAt: 0
|
|
1308
|
+
};
|
|
1309
|
+
return routeMatch;
|
|
1310
|
+
});
|
|
2473
1311
|
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
1312
|
+
// Take each match and resolve its search params and context
|
|
1313
|
+
// This has to happen after the matches are created or found
|
|
1314
|
+
// so that we can use the parent match's search params and context
|
|
1315
|
+
matches.forEach((match, i) => {
|
|
1316
|
+
const parentMatch = matches[i - 1];
|
|
1317
|
+
const route = looseRoutesById[match.routeId];
|
|
1318
|
+
const searchInfo = (() => {
|
|
1319
|
+
// Validate the search params and stabilize them
|
|
1320
|
+
const parentSearchInfo = {
|
|
1321
|
+
search: parentMatch?.search ?? locationSearch,
|
|
1322
|
+
routeSearch: parentMatch?.routeSearch ?? locationSearch
|
|
1323
|
+
};
|
|
1324
|
+
try {
|
|
1325
|
+
const validator = typeof route.options.validateSearch === 'object' ? route.options.validateSearch.parse : route.options.validateSearch;
|
|
1326
|
+
let routeSearch = validator?.(parentSearchInfo.search) ?? {};
|
|
1327
|
+
let search = {
|
|
1328
|
+
...parentSearchInfo.search,
|
|
1329
|
+
...routeSearch
|
|
1330
|
+
};
|
|
1331
|
+
routeSearch = replaceEqualDeep(match.routeSearch, routeSearch);
|
|
1332
|
+
search = replaceEqualDeep(match.search, search);
|
|
1333
|
+
return {
|
|
1334
|
+
routeSearch,
|
|
1335
|
+
search,
|
|
1336
|
+
searchDidChange: match.routeSearch !== routeSearch
|
|
1337
|
+
};
|
|
1338
|
+
} catch (err) {
|
|
1339
|
+
match.searchError = new SearchParamError(err.message, {
|
|
1340
|
+
cause: err
|
|
2489
1341
|
});
|
|
1342
|
+
if (opts?.throwOnError) {
|
|
1343
|
+
throw match.searchError;
|
|
1344
|
+
}
|
|
1345
|
+
return parentSearchInfo;
|
|
2490
1346
|
}
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
1347
|
+
})();
|
|
1348
|
+
Object.assign(match, searchInfo);
|
|
1349
|
+
});
|
|
1350
|
+
return matches;
|
|
1351
|
+
});
|
|
1352
|
+
const cancelMatch = useStableCallback(id => {
|
|
1353
|
+
getRouteMatch(state, id)?.abortController?.abort();
|
|
1354
|
+
});
|
|
1355
|
+
const cancelMatches = useStableCallback(state => {
|
|
1356
|
+
state.matches.forEach(match => {
|
|
1357
|
+
cancelMatch(match.id);
|
|
1358
|
+
});
|
|
1359
|
+
});
|
|
1360
|
+
const buildLocation = useStableCallback(opts => {
|
|
1361
|
+
const build = (dest = {}, matches) => {
|
|
1362
|
+
const from = latestLocationRef.current;
|
|
1363
|
+
const fromPathname = dest.from ?? from.pathname;
|
|
1364
|
+
let pathname = resolvePathWithBase(fromPathname, `${dest.to ?? ''}`);
|
|
1365
|
+
const fromMatches = matchRoutes(fromPathname, from.search);
|
|
1366
|
+
const stayingMatches = matches?.filter(d => fromMatches?.find(e => e.routeId === d.routeId));
|
|
1367
|
+
const prevParams = {
|
|
1368
|
+
...last(fromMatches)?.params
|
|
1369
|
+
};
|
|
1370
|
+
let nextParams = (dest.params ?? true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
1371
|
+
if (nextParams) {
|
|
1372
|
+
matches?.map(d => looseRoutesById[d.routeId].options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
1373
|
+
nextParams = {
|
|
1374
|
+
...nextParams,
|
|
1375
|
+
...fn(nextParams)
|
|
2498
1376
|
};
|
|
2499
1377
|
});
|
|
2500
|
-
return router.navigationPromise;
|
|
2501
1378
|
}
|
|
1379
|
+
pathname = interpolatePath(pathname, nextParams ?? {});
|
|
1380
|
+
const preSearchFilters = stayingMatches?.map(match => looseRoutesById[match.routeId].options.preSearchFilters ?? []).flat().filter(Boolean) ?? [];
|
|
1381
|
+
const postSearchFilters = stayingMatches?.map(match => looseRoutesById[match.routeId].options.postSearchFilters ?? []).flat().filter(Boolean) ?? [];
|
|
1382
|
+
|
|
1383
|
+
// Pre filters first
|
|
1384
|
+
const preFilteredSearch = preSearchFilters?.length ? preSearchFilters?.reduce((prev, next) => next(prev), from.search) : from.search;
|
|
1385
|
+
|
|
1386
|
+
// Then the link/navigate function
|
|
1387
|
+
const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
|
|
1388
|
+
: dest.search ? functionalUpdate(dest.search, preFilteredSearch) ?? {} // Updater
|
|
1389
|
+
: preSearchFilters?.length ? preFilteredSearch // Preserve resolvedFrom filters
|
|
1390
|
+
: {};
|
|
1391
|
+
|
|
1392
|
+
// Then post filters
|
|
1393
|
+
const postFilteredSearch = postSearchFilters?.length ? postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
1394
|
+
const search = replaceEqualDeep(from.search, postFilteredSearch);
|
|
1395
|
+
const searchStr = options.stringifySearch(search);
|
|
1396
|
+
const hash = dest.hash === true ? from.hash : dest.hash ? functionalUpdate(dest.hash, from.hash) : from.hash;
|
|
1397
|
+
const hashStr = hash ? `#${hash}` : '';
|
|
1398
|
+
let nextState = dest.state === true ? from.state : dest.state ? functionalUpdate(dest.state, from.state) : from.state;
|
|
1399
|
+
nextState = replaceEqualDeep(from.state, nextState);
|
|
1400
|
+
return {
|
|
1401
|
+
pathname,
|
|
1402
|
+
search,
|
|
1403
|
+
searchStr,
|
|
1404
|
+
state: nextState,
|
|
1405
|
+
hash,
|
|
1406
|
+
href: history.createHref(`${pathname}${searchStr}${hashStr}`),
|
|
1407
|
+
unmaskOnReload: dest.unmaskOnReload
|
|
1408
|
+
};
|
|
1409
|
+
};
|
|
1410
|
+
const buildWithMatches = (dest = {}, maskedDest) => {
|
|
1411
|
+
let next = build(dest);
|
|
1412
|
+
let maskedNext = maskedDest ? build(maskedDest) : undefined;
|
|
1413
|
+
if (!maskedNext) {
|
|
1414
|
+
let params = {};
|
|
1415
|
+
let foundMask = options.routeMasks?.find(d => {
|
|
1416
|
+
const match = matchPathname(basepath, next.pathname, {
|
|
1417
|
+
to: d.from,
|
|
1418
|
+
caseSensitive: false,
|
|
1419
|
+
fuzzy: false
|
|
1420
|
+
});
|
|
1421
|
+
if (match) {
|
|
1422
|
+
params = match;
|
|
1423
|
+
return true;
|
|
1424
|
+
}
|
|
1425
|
+
return false;
|
|
1426
|
+
});
|
|
1427
|
+
if (foundMask) {
|
|
1428
|
+
foundMask = {
|
|
1429
|
+
...foundMask,
|
|
1430
|
+
from: interpolatePath(foundMask.from, params)
|
|
1431
|
+
};
|
|
1432
|
+
maskedDest = foundMask;
|
|
1433
|
+
maskedNext = build(maskedDest);
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
const nextMatches = matchRoutes(next.pathname, next.search);
|
|
1437
|
+
const maskedMatches = maskedNext ? matchRoutes(maskedNext.pathname, maskedNext.search) : undefined;
|
|
1438
|
+
const maskedFinal = maskedNext ? build(maskedDest, maskedMatches) : undefined;
|
|
1439
|
+
const final = build(dest, nextMatches);
|
|
1440
|
+
if (maskedFinal) {
|
|
1441
|
+
final.maskedLocation = maskedFinal;
|
|
1442
|
+
}
|
|
1443
|
+
return final;
|
|
1444
|
+
};
|
|
1445
|
+
if (opts.mask) {
|
|
1446
|
+
return buildWithMatches(opts, {
|
|
1447
|
+
...pick(opts, ['from']),
|
|
1448
|
+
...opts.mask
|
|
1449
|
+
});
|
|
2502
1450
|
}
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
}
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
1451
|
+
return buildWithMatches(opts);
|
|
1452
|
+
});
|
|
1453
|
+
const commitLocation = useStableCallback(async ({
|
|
1454
|
+
startTransition,
|
|
1455
|
+
...next
|
|
1456
|
+
}) => {
|
|
1457
|
+
if (navigateTimeoutRef.current) clearTimeout(navigateTimeoutRef.current);
|
|
1458
|
+
const isSameUrl = latestLocationRef.current.href === next.href;
|
|
1459
|
+
|
|
1460
|
+
// If the next urls are the same and we're not replacing,
|
|
1461
|
+
// do nothing
|
|
1462
|
+
if (!isSameUrl || !next.replace) {
|
|
1463
|
+
let {
|
|
1464
|
+
maskedLocation,
|
|
1465
|
+
...nextHistory
|
|
1466
|
+
} = next;
|
|
1467
|
+
if (maskedLocation) {
|
|
1468
|
+
nextHistory = {
|
|
1469
|
+
...maskedLocation,
|
|
1470
|
+
state: {
|
|
1471
|
+
...maskedLocation.state,
|
|
1472
|
+
__tempKey: undefined,
|
|
1473
|
+
__tempLocation: {
|
|
1474
|
+
...nextHistory,
|
|
1475
|
+
search: nextHistory.searchStr,
|
|
1476
|
+
state: {
|
|
1477
|
+
...nextHistory.state,
|
|
1478
|
+
__tempKey: undefined,
|
|
1479
|
+
__tempLocation: undefined,
|
|
1480
|
+
key: undefined
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1485
|
+
if (nextHistory.unmaskOnReload ?? options.unmaskOnReload ?? false) {
|
|
1486
|
+
nextHistory.state.__tempKey = tempLocationKeyRef.current;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
const apply = () => {
|
|
1490
|
+
history[next.replace ? 'replace' : 'push'](nextHistory.href, nextHistory.state);
|
|
1491
|
+
};
|
|
1492
|
+
if (startTransition ?? true) {
|
|
1493
|
+
startReactTransition(apply);
|
|
1494
|
+
} else {
|
|
1495
|
+
apply();
|
|
1496
|
+
}
|
|
2520
1497
|
}
|
|
1498
|
+
resetNextScrollRef.current = next.resetScroll ?? true;
|
|
1499
|
+
return latestLoadPromiseRef.current;
|
|
2521
1500
|
});
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
} : {}, props));
|
|
1501
|
+
const buildAndCommitLocation = useStableCallback(({
|
|
1502
|
+
replace,
|
|
1503
|
+
resetScroll,
|
|
1504
|
+
startTransition,
|
|
1505
|
+
...rest
|
|
1506
|
+
} = {}) => {
|
|
1507
|
+
const location = buildLocation(rest);
|
|
1508
|
+
return commitLocation({
|
|
1509
|
+
...location,
|
|
1510
|
+
startTransition,
|
|
1511
|
+
replace,
|
|
1512
|
+
resetScroll
|
|
1513
|
+
});
|
|
2536
1514
|
});
|
|
2537
|
-
const
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
1515
|
+
const navigate = useStableCallback(({
|
|
1516
|
+
from,
|
|
1517
|
+
to = '',
|
|
1518
|
+
...rest
|
|
1519
|
+
}) => {
|
|
1520
|
+
// If this link simply reloads the current route,
|
|
1521
|
+
// make sure it has a new key so it will trigger a data refresh
|
|
1522
|
+
|
|
1523
|
+
// If this `to` is a valid external URL, return
|
|
1524
|
+
// null for LinkUtils
|
|
1525
|
+
const toString = String(to);
|
|
1526
|
+
const fromString = typeof from === 'undefined' ? from : String(from);
|
|
1527
|
+
let isExternal;
|
|
1528
|
+
try {
|
|
1529
|
+
new URL(`${toString}`);
|
|
1530
|
+
isExternal = true;
|
|
1531
|
+
} catch (e) {}
|
|
1532
|
+
invariant(!isExternal, 'Attempting to navigate to external url with this.navigate!');
|
|
1533
|
+
return buildAndCommitLocation({
|
|
1534
|
+
...rest,
|
|
1535
|
+
from: fromString,
|
|
1536
|
+
to: toString
|
|
1537
|
+
});
|
|
1538
|
+
});
|
|
1539
|
+
const loadMatches = useStableCallback(async ({
|
|
1540
|
+
checkLatest,
|
|
1541
|
+
matches,
|
|
1542
|
+
preload
|
|
1543
|
+
}) => {
|
|
1544
|
+
let latestPromise;
|
|
1545
|
+
let firstBadMatchIndex;
|
|
1546
|
+
|
|
1547
|
+
// Check each match middleware to see if the route can be accessed
|
|
1548
|
+
try {
|
|
1549
|
+
for (let [index, match] of matches.entries()) {
|
|
1550
|
+
const parentMatch = matches[index - 1];
|
|
1551
|
+
const route = looseRoutesById[match.routeId];
|
|
1552
|
+
const handleError = (err, code) => {
|
|
1553
|
+
err.routerCode = code;
|
|
1554
|
+
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
1555
|
+
if (isRedirect(err)) {
|
|
1556
|
+
throw err;
|
|
1557
|
+
}
|
|
1558
|
+
try {
|
|
1559
|
+
route.options.onError?.(err);
|
|
1560
|
+
} catch (errorHandlerErr) {
|
|
1561
|
+
err = errorHandlerErr;
|
|
1562
|
+
if (isRedirect(errorHandlerErr)) {
|
|
1563
|
+
throw errorHandlerErr;
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
matches[index] = match = {
|
|
1567
|
+
...match,
|
|
1568
|
+
error: err,
|
|
1569
|
+
status: 'error',
|
|
1570
|
+
updatedAt: Date.now()
|
|
1571
|
+
};
|
|
1572
|
+
};
|
|
1573
|
+
try {
|
|
1574
|
+
if (match.paramsError) {
|
|
1575
|
+
handleError(match.paramsError, 'PARSE_PARAMS');
|
|
1576
|
+
}
|
|
1577
|
+
if (match.searchError) {
|
|
1578
|
+
handleError(match.searchError, 'VALIDATE_SEARCH');
|
|
1579
|
+
}
|
|
1580
|
+
const parentContext = parentMatch?.context ?? options.context ?? {};
|
|
1581
|
+
const beforeLoadContext = (await route.options.beforeLoad?.({
|
|
1582
|
+
search: match.search,
|
|
1583
|
+
abortController: match.abortController,
|
|
1584
|
+
params: match.params,
|
|
1585
|
+
preload: !!preload,
|
|
1586
|
+
context: parentContext,
|
|
1587
|
+
location: state.location,
|
|
1588
|
+
navigate: opts => navigate({
|
|
1589
|
+
...opts,
|
|
1590
|
+
from: match.pathname
|
|
1591
|
+
}),
|
|
1592
|
+
buildLocation
|
|
1593
|
+
})) ?? {};
|
|
1594
|
+
const context = {
|
|
1595
|
+
...parentContext,
|
|
1596
|
+
...beforeLoadContext
|
|
1597
|
+
};
|
|
1598
|
+
matches[index] = match = {
|
|
1599
|
+
...match,
|
|
1600
|
+
context: replaceEqualDeep(match.context, context)
|
|
1601
|
+
};
|
|
1602
|
+
} catch (err) {
|
|
1603
|
+
handleError(err, 'BEFORE_LOAD');
|
|
1604
|
+
break;
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
} catch (err) {
|
|
1608
|
+
if (isRedirect(err)) {
|
|
1609
|
+
if (!preload) navigate(err);
|
|
1610
|
+
return matches;
|
|
1611
|
+
}
|
|
1612
|
+
throw err;
|
|
2545
1613
|
}
|
|
1614
|
+
const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
|
|
1615
|
+
const matchPromises = [];
|
|
1616
|
+
validResolvedMatches.forEach((match, index) => {
|
|
1617
|
+
matchPromises.push((async () => {
|
|
1618
|
+
const parentMatchPromise = matchPromises[index - 1];
|
|
1619
|
+
const route = looseRoutesById[match.routeId];
|
|
1620
|
+
const handleIfRedirect = err => {
|
|
1621
|
+
if (isRedirect(err)) {
|
|
1622
|
+
if (!preload) {
|
|
1623
|
+
navigate(err);
|
|
1624
|
+
}
|
|
1625
|
+
return true;
|
|
1626
|
+
}
|
|
1627
|
+
return false;
|
|
1628
|
+
};
|
|
1629
|
+
let loadPromise;
|
|
1630
|
+
matches[index] = match = {
|
|
1631
|
+
...match,
|
|
1632
|
+
fetchedAt: Date.now(),
|
|
1633
|
+
invalid: false
|
|
1634
|
+
};
|
|
1635
|
+
if (match.isFetching) {
|
|
1636
|
+
loadPromise = getRouteMatch(state, match.id)?.loadPromise;
|
|
1637
|
+
} else {
|
|
1638
|
+
const cause = state.matches.find(d => d.id === match.id) ? 'stay' : 'enter';
|
|
1639
|
+
const loaderContext = {
|
|
1640
|
+
params: match.params,
|
|
1641
|
+
search: match.search,
|
|
1642
|
+
preload: !!preload,
|
|
1643
|
+
parentMatchPromise,
|
|
1644
|
+
abortController: match.abortController,
|
|
1645
|
+
context: match.context,
|
|
1646
|
+
location: state.location,
|
|
1647
|
+
navigate: opts => navigate({
|
|
1648
|
+
...opts,
|
|
1649
|
+
from: match.pathname
|
|
1650
|
+
}),
|
|
1651
|
+
cause
|
|
1652
|
+
};
|
|
2546
1653
|
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
//
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
function MatchesProvider(props) {
|
|
2560
|
-
return /*#__PURE__*/React.createElement(matchesContext.Provider, props);
|
|
2561
|
-
}
|
|
1654
|
+
// Default to reloading the route all the time
|
|
1655
|
+
let shouldReload = true;
|
|
1656
|
+
if (cause !== 'enter') {
|
|
1657
|
+
let shouldReloadDeps = typeof route.options.shouldReload === 'function' ? route.options.shouldReload?.(loaderContext) : !!(route.options.shouldReload ?? true);
|
|
1658
|
+
if (typeof shouldReloadDeps === 'object') {
|
|
1659
|
+
// compare the deps to see if they've changed
|
|
1660
|
+
shouldReload = !deepEqual(shouldReloadDeps, match.shouldReloadDeps);
|
|
1661
|
+
match.shouldReloadDeps = shouldReloadDeps;
|
|
1662
|
+
} else {
|
|
1663
|
+
shouldReload = !!shouldReloadDeps;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
2562
1666
|
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
};
|
|
1667
|
+
// If the user doesn't want the route to reload, just
|
|
1668
|
+
// resolve with the existing loader data
|
|
2566
1669
|
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
1670
|
+
if (!shouldReload) {
|
|
1671
|
+
loadPromise = Promise.resolve(match.loaderData);
|
|
1672
|
+
} else {
|
|
1673
|
+
// Otherwise, load the route
|
|
1674
|
+
matches[index] = match = {
|
|
1675
|
+
...match,
|
|
1676
|
+
isFetching: true
|
|
1677
|
+
};
|
|
1678
|
+
const componentsPromise = Promise.all(componentTypes.map(async type => {
|
|
1679
|
+
const component = route.options[type];
|
|
1680
|
+
if (component?.preload) {
|
|
1681
|
+
await component.preload();
|
|
1682
|
+
}
|
|
1683
|
+
}));
|
|
1684
|
+
const loaderPromise = route.options.loader?.(loaderContext);
|
|
1685
|
+
loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
|
|
1686
|
+
}
|
|
2573
1687
|
}
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
1688
|
+
matches[index] = match = {
|
|
1689
|
+
...match,
|
|
1690
|
+
loadPromise
|
|
1691
|
+
};
|
|
1692
|
+
if (!preload) {
|
|
1693
|
+
setState(s => ({
|
|
1694
|
+
...s,
|
|
1695
|
+
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
1696
|
+
}));
|
|
1697
|
+
}
|
|
1698
|
+
try {
|
|
1699
|
+
const loaderData = await loadPromise;
|
|
1700
|
+
if (latestPromise = checkLatest()) return await latestPromise;
|
|
1701
|
+
matches[index] = match = {
|
|
1702
|
+
...match,
|
|
1703
|
+
error: undefined,
|
|
1704
|
+
status: 'success',
|
|
1705
|
+
isFetching: false,
|
|
1706
|
+
updatedAt: Date.now(),
|
|
1707
|
+
loaderData,
|
|
1708
|
+
loadPromise: undefined
|
|
1709
|
+
};
|
|
1710
|
+
} catch (error) {
|
|
1711
|
+
if (latestPromise = checkLatest()) return await latestPromise;
|
|
1712
|
+
if (handleIfRedirect(error)) return;
|
|
1713
|
+
try {
|
|
1714
|
+
route.options.onError?.(error);
|
|
1715
|
+
} catch (onErrorError) {
|
|
1716
|
+
error = onErrorError;
|
|
1717
|
+
if (handleIfRedirect(onErrorError)) return;
|
|
1718
|
+
}
|
|
1719
|
+
matches[index] = match = {
|
|
1720
|
+
...match,
|
|
1721
|
+
error,
|
|
1722
|
+
status: 'error',
|
|
1723
|
+
isFetching: false,
|
|
1724
|
+
updatedAt: Date.now()
|
|
2610
1725
|
};
|
|
2611
1726
|
}
|
|
1727
|
+
if (!preload) {
|
|
1728
|
+
setState(s => ({
|
|
1729
|
+
...s,
|
|
1730
|
+
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
1731
|
+
}));
|
|
1732
|
+
}
|
|
1733
|
+
})());
|
|
1734
|
+
});
|
|
1735
|
+
await Promise.all(matchPromises);
|
|
1736
|
+
return matches;
|
|
1737
|
+
});
|
|
1738
|
+
const load = useStableCallback(async () => {
|
|
1739
|
+
const promise = new Promise(async (resolve, reject) => {
|
|
1740
|
+
const next = latestLocationRef.current;
|
|
1741
|
+
const prevLocation = state.resolvedLocation;
|
|
1742
|
+
const pathDidChange = prevLocation.href !== next.href;
|
|
1743
|
+
let latestPromise;
|
|
1744
|
+
|
|
1745
|
+
// Cancel any pending matches
|
|
1746
|
+
cancelMatches(state);
|
|
1747
|
+
router.emit({
|
|
1748
|
+
type: 'onBeforeLoad',
|
|
1749
|
+
fromLocation: prevLocation,
|
|
1750
|
+
toLocation: next,
|
|
1751
|
+
pathChanged: pathDidChange
|
|
1752
|
+
});
|
|
2612
1753
|
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
1754
|
+
// Match the routes
|
|
1755
|
+
let matches = matchRoutes(next.pathname, next.search, {
|
|
1756
|
+
debug: true
|
|
1757
|
+
});
|
|
1758
|
+
pendingMatchesRef.current = matches;
|
|
1759
|
+
const previousMatches = state.matches;
|
|
1760
|
+
|
|
1761
|
+
// Ingest the new matches
|
|
1762
|
+
setState(s => ({
|
|
1763
|
+
...s,
|
|
1764
|
+
status: 'pending',
|
|
1765
|
+
location: next,
|
|
1766
|
+
matches
|
|
1767
|
+
}));
|
|
1768
|
+
try {
|
|
1769
|
+
try {
|
|
1770
|
+
// Load the matches
|
|
1771
|
+
await loadMatches({
|
|
1772
|
+
matches,
|
|
1773
|
+
checkLatest: () => checkLatest(promise)
|
|
2625
1774
|
});
|
|
2626
|
-
}
|
|
1775
|
+
} catch (err) {
|
|
1776
|
+
// swallow this error, since we'll display the
|
|
1777
|
+
// errors on the route components
|
|
1778
|
+
}
|
|
2627
1779
|
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
1780
|
+
// Only apply the latest transition
|
|
1781
|
+
if (latestPromise = checkLatest(promise)) {
|
|
1782
|
+
return latestPromise;
|
|
1783
|
+
}
|
|
1784
|
+
const exitingMatchIds = previousMatches.filter(id => !pendingMatchesRef.current.includes(id));
|
|
1785
|
+
const enteringMatchIds = pendingMatchesRef.current.filter(id => !previousMatches.includes(id));
|
|
1786
|
+
const stayingMatchIds = previousMatches.filter(id => pendingMatchesRef.current.includes(id))
|
|
1787
|
+
|
|
1788
|
+
// setState((s) => ({
|
|
1789
|
+
// ...s,
|
|
1790
|
+
// status: 'idle',
|
|
1791
|
+
// resolvedLocation: s.location,
|
|
1792
|
+
// }))
|
|
1793
|
+
|
|
1794
|
+
//
|
|
1795
|
+
;
|
|
1796
|
+
[[exitingMatchIds, 'onLeave'], [enteringMatchIds, 'onEnter'], [stayingMatchIds, 'onTransition']].forEach(([matches, hook]) => {
|
|
1797
|
+
matches.forEach(match => {
|
|
1798
|
+
looseRoutesById[match.routeId].options[hook]?.(match);
|
|
2632
1799
|
});
|
|
2633
|
-
}; // Get the active props
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
const resolvedActiveProps = isActive ? (_functionalUpdate = functionalUpdate(activeProps, {})) != null ? _functionalUpdate : {} : {}; // Get the inactive props
|
|
2637
|
-
|
|
2638
|
-
const resolvedInactiveProps = isActive ? {} : (_functionalUpdate2 = functionalUpdate(inactiveProps, {})) != null ? _functionalUpdate2 : {};
|
|
2639
|
-
return _extends$2({}, resolvedActiveProps, resolvedInactiveProps, rest, {
|
|
2640
|
-
href: disabled ? undefined : next.href,
|
|
2641
|
-
onClick: composeHandlers([reactHandleClick, onClick]),
|
|
2642
|
-
onFocus: composeHandlers([handleFocus, onFocus]),
|
|
2643
|
-
onMouseEnter: composeHandlers([handleEnter, onMouseEnter]),
|
|
2644
|
-
onMouseLeave: composeHandlers([handleLeave, onMouseLeave]),
|
|
2645
|
-
target,
|
|
2646
|
-
style: _extends$2({}, style, resolvedActiveProps.style, resolvedInactiveProps.style),
|
|
2647
|
-
className: [className, resolvedActiveProps.className, resolvedInactiveProps.className].filter(Boolean).join(' ') || undefined
|
|
2648
|
-
}, disabled ? {
|
|
2649
|
-
role: 'link',
|
|
2650
|
-
'aria-disabled': true
|
|
2651
|
-
} : undefined, {
|
|
2652
|
-
['data-status']: isActive ? 'active' : undefined
|
|
2653
1800
|
});
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
ref: ref
|
|
2660
|
-
}, linkProps, {
|
|
2661
|
-
children: typeof props.children === 'function' ? props.children({
|
|
2662
|
-
isActive: linkProps['data-status'] === 'active'
|
|
2663
|
-
}) : props.children
|
|
2664
|
-
}));
|
|
2665
|
-
}),
|
|
2666
|
-
MatchRoute: opts => {
|
|
2667
|
-
const {
|
|
2668
|
-
pending,
|
|
2669
|
-
caseSensitive
|
|
2670
|
-
} = opts,
|
|
2671
|
-
rest = _objectWithoutPropertiesLoose(opts, _excluded2);
|
|
2672
|
-
|
|
2673
|
-
const params = route.matchRoute(rest, {
|
|
2674
|
-
pending,
|
|
2675
|
-
caseSensitive
|
|
1801
|
+
router.emit({
|
|
1802
|
+
type: 'onLoad',
|
|
1803
|
+
fromLocation: prevLocation,
|
|
1804
|
+
toLocation: next,
|
|
1805
|
+
pathChanged: pathDidChange
|
|
2676
1806
|
});
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
1807
|
+
resolve();
|
|
1808
|
+
} catch (err) {
|
|
1809
|
+
// Only apply the latest transition
|
|
1810
|
+
if (latestPromise = checkLatest(promise)) {
|
|
1811
|
+
return latestPromise;
|
|
2680
1812
|
}
|
|
2681
|
-
|
|
2682
|
-
|
|
1813
|
+
reject(err);
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
latestLoadPromiseRef.current = promise;
|
|
1817
|
+
return latestLoadPromiseRef.current;
|
|
1818
|
+
});
|
|
1819
|
+
const preloadRoute = useStableCallback(async (navigateOpts = state.location) => {
|
|
1820
|
+
let next = buildLocation(navigateOpts);
|
|
1821
|
+
let matches = matchRoutes(next.pathname, next.search, {
|
|
1822
|
+
throwOnError: true
|
|
1823
|
+
});
|
|
1824
|
+
await loadMatches({
|
|
1825
|
+
matches,
|
|
1826
|
+
preload: true,
|
|
1827
|
+
checkLatest: () => undefined
|
|
1828
|
+
});
|
|
1829
|
+
return [last(matches), matches];
|
|
1830
|
+
});
|
|
1831
|
+
const buildLink = useStableCallback(dest => {
|
|
1832
|
+
// If this link simply reloads the current route,
|
|
1833
|
+
// make sure it has a new key so it will trigger a data refresh
|
|
1834
|
+
|
|
1835
|
+
// If this `to` is a valid external URL, return
|
|
1836
|
+
// null for LinkUtils
|
|
1837
|
+
|
|
1838
|
+
const {
|
|
1839
|
+
to,
|
|
1840
|
+
preload: userPreload,
|
|
1841
|
+
preloadDelay: userPreloadDelay,
|
|
1842
|
+
activeOptions,
|
|
1843
|
+
disabled,
|
|
1844
|
+
target,
|
|
1845
|
+
replace,
|
|
1846
|
+
resetScroll,
|
|
1847
|
+
startTransition
|
|
1848
|
+
} = dest;
|
|
1849
|
+
try {
|
|
1850
|
+
new URL(`${to}`);
|
|
1851
|
+
return {
|
|
1852
|
+
type: 'external',
|
|
1853
|
+
href: to
|
|
1854
|
+
};
|
|
1855
|
+
} catch (e) {}
|
|
1856
|
+
const nextOpts = dest;
|
|
1857
|
+
const next = buildLocation(nextOpts);
|
|
1858
|
+
const preload = userPreload ?? options.defaultPreload;
|
|
1859
|
+
const preloadDelay = userPreloadDelay ?? options.defaultPreloadDelay ?? 0;
|
|
1860
|
+
|
|
1861
|
+
// Compare path/hash for matches
|
|
1862
|
+
const currentPathSplit = latestLocationRef.current.pathname.split('/');
|
|
1863
|
+
const nextPathSplit = next.pathname.split('/');
|
|
1864
|
+
const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
|
|
1865
|
+
// Combine the matches based on user options
|
|
1866
|
+
const pathTest = activeOptions?.exact ? latestLocationRef.current.pathname === next.pathname : pathIsFuzzyEqual;
|
|
1867
|
+
const hashTest = activeOptions?.includeHash ? latestLocationRef.current.hash === next.hash : true;
|
|
1868
|
+
const searchTest = activeOptions?.includeSearch ?? true ? deepEqual(latestLocationRef.current.search, next.search, true) : true;
|
|
1869
|
+
|
|
1870
|
+
// The final "active" test
|
|
1871
|
+
const isActive = pathTest && hashTest && searchTest;
|
|
1872
|
+
|
|
1873
|
+
// The click handler
|
|
1874
|
+
const handleClick = e => {
|
|
1875
|
+
if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
|
|
1876
|
+
e.preventDefault();
|
|
1877
|
+
|
|
1878
|
+
// All is well? Navigate!
|
|
1879
|
+
commitLocation({
|
|
1880
|
+
...next,
|
|
1881
|
+
replace,
|
|
1882
|
+
resetScroll,
|
|
1883
|
+
startTransition
|
|
1884
|
+
});
|
|
2683
1885
|
}
|
|
2684
1886
|
};
|
|
2685
|
-
};
|
|
2686
1887
|
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
}
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
return match;
|
|
1888
|
+
// The click handler
|
|
1889
|
+
const handleFocus = e => {
|
|
1890
|
+
if (preload) {
|
|
1891
|
+
preloadRoute(nextOpts).catch(err => {
|
|
1892
|
+
console.warn(err);
|
|
1893
|
+
console.warn(preloadWarning);
|
|
1894
|
+
});
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
const handleTouchStart = e => {
|
|
1898
|
+
preloadRoute(nextOpts).catch(err => {
|
|
1899
|
+
console.warn(err);
|
|
1900
|
+
console.warn(preloadWarning);
|
|
1901
|
+
});
|
|
1902
|
+
};
|
|
1903
|
+
const handleEnter = e => {
|
|
1904
|
+
const target = e.target || {};
|
|
1905
|
+
if (preload) {
|
|
1906
|
+
if (target.preloadTimeout) {
|
|
1907
|
+
return;
|
|
2708
1908
|
}
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
route
|
|
2717
|
-
} = _ref;
|
|
2718
|
-
const routeExt = makeRouteExt(route, router);
|
|
2719
|
-
Object.assign(route, routeExt);
|
|
2720
|
-
},
|
|
2721
|
-
loadComponent: async component => {
|
|
2722
|
-
if (component.preload && typeof document !== 'undefined') {
|
|
2723
|
-
component.preload(); // return await component.preload()
|
|
1909
|
+
target.preloadTimeout = setTimeout(() => {
|
|
1910
|
+
target.preloadTimeout = null;
|
|
1911
|
+
preloadRoute(nextOpts).catch(err => {
|
|
1912
|
+
console.warn(err);
|
|
1913
|
+
console.warn(preloadWarning);
|
|
1914
|
+
});
|
|
1915
|
+
}, preloadDelay);
|
|
2724
1916
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
1917
|
+
};
|
|
1918
|
+
const handleLeave = e => {
|
|
1919
|
+
const target = e.target || {};
|
|
1920
|
+
if (target.preloadTimeout) {
|
|
1921
|
+
clearTimeout(target.preloadTimeout);
|
|
1922
|
+
target.preloadTimeout = null;
|
|
1923
|
+
}
|
|
1924
|
+
};
|
|
1925
|
+
return {
|
|
1926
|
+
type: 'internal',
|
|
1927
|
+
next,
|
|
1928
|
+
handleFocus,
|
|
1929
|
+
handleClick,
|
|
1930
|
+
handleEnter,
|
|
1931
|
+
handleLeave,
|
|
1932
|
+
handleTouchStart,
|
|
1933
|
+
isActive,
|
|
1934
|
+
disabled
|
|
1935
|
+
};
|
|
1936
|
+
});
|
|
1937
|
+
React.useLayoutEffect(() => {
|
|
1938
|
+
const unsub = history.subscribe(() => {
|
|
1939
|
+
latestLocationRef.current = parseLocation(latestLocationRef.current);
|
|
1940
|
+
if (state.location !== latestLocationRef.current) {
|
|
1941
|
+
startReactTransition(() => {
|
|
1942
|
+
try {
|
|
1943
|
+
load();
|
|
1944
|
+
} catch (err) {
|
|
1945
|
+
console.error(err);
|
|
1946
|
+
}
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
});
|
|
1950
|
+
const nextLocation = buildLocation({
|
|
1951
|
+
search: true,
|
|
1952
|
+
params: true,
|
|
1953
|
+
hash: true,
|
|
1954
|
+
state: true
|
|
1955
|
+
});
|
|
1956
|
+
if (state.location.href !== nextLocation.href) {
|
|
1957
|
+
commitLocation({
|
|
1958
|
+
...nextLocation,
|
|
1959
|
+
replace: true
|
|
1960
|
+
});
|
|
2727
1961
|
}
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
}
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
1962
|
+
return () => {
|
|
1963
|
+
unsub();
|
|
1964
|
+
};
|
|
1965
|
+
}, [history]);
|
|
1966
|
+
const matchRoute = useStableCallback((location, opts) => {
|
|
1967
|
+
location = {
|
|
1968
|
+
...location,
|
|
1969
|
+
to: location.to ? resolvePathWithBase(location.from || '', location.to) : undefined
|
|
1970
|
+
};
|
|
1971
|
+
const next = buildLocation(location);
|
|
1972
|
+
if (opts?.pending && state.status !== 'pending') {
|
|
1973
|
+
return false;
|
|
1974
|
+
}
|
|
1975
|
+
const baseLocation = opts?.pending ? latestLocationRef.current : state.resolvedLocation;
|
|
2737
1976
|
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
1977
|
+
// const baseLocation = state.resolvedLocation
|
|
1978
|
+
|
|
1979
|
+
if (!baseLocation) {
|
|
1980
|
+
return false;
|
|
1981
|
+
}
|
|
1982
|
+
const match = matchPathname(basepath, baseLocation.pathname, {
|
|
1983
|
+
...opts,
|
|
1984
|
+
to: next.pathname
|
|
1985
|
+
});
|
|
1986
|
+
if (!match) {
|
|
1987
|
+
return false;
|
|
1988
|
+
}
|
|
1989
|
+
if (match && (opts?.includeSearch ?? true)) {
|
|
1990
|
+
return deepEqual(baseLocation.search, next.search, true) ? match : false;
|
|
1991
|
+
}
|
|
1992
|
+
return match;
|
|
1993
|
+
});
|
|
1994
|
+
const injectedHtmlRef = React.useRef([]);
|
|
1995
|
+
const injectHtml = useStableCallback(async html => {
|
|
1996
|
+
injectedHtmlRef.current.push(html);
|
|
1997
|
+
});
|
|
1998
|
+
const dehydrateData = useStableCallback((key, getData) => {
|
|
1999
|
+
if (typeof document === 'undefined') {
|
|
2000
|
+
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2001
|
+
injectHtml(async () => {
|
|
2002
|
+
const id = `__TSR_DEHYDRATED__${strKey}`;
|
|
2003
|
+
const data = typeof getData === 'function' ? await getData() : getData;
|
|
2004
|
+
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(strKey)}"] = ${JSON.stringify(data)}
|
|
2005
|
+
;(() => {
|
|
2006
|
+
var el = document.getElementById('${id}')
|
|
2007
|
+
el.parentElement.removeChild(el)
|
|
2008
|
+
})()
|
|
2009
|
+
</script>`;
|
|
2010
|
+
});
|
|
2011
|
+
return () => hydrateData(key);
|
|
2012
|
+
}
|
|
2013
|
+
return () => undefined;
|
|
2014
|
+
});
|
|
2015
|
+
const hydrateData = useStableCallback(key => {
|
|
2016
|
+
if (typeof document !== 'undefined') {
|
|
2017
|
+
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2018
|
+
return window[`__TSR_DEHYDRATED__${strKey}`];
|
|
2747
2019
|
}
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2020
|
+
return undefined;
|
|
2021
|
+
});
|
|
2022
|
+
React.useLayoutEffect(() => {
|
|
2023
|
+
startReactTransition(() => {
|
|
2024
|
+
try {
|
|
2025
|
+
load();
|
|
2026
|
+
} catch (err) {
|
|
2027
|
+
console.error(err);
|
|
2028
|
+
}
|
|
2029
|
+
});
|
|
2030
|
+
}, []);
|
|
2031
|
+
const routerContextValue = {
|
|
2032
|
+
routeTree: router.routeTree,
|
|
2033
|
+
navigate,
|
|
2034
|
+
buildLink,
|
|
2035
|
+
state,
|
|
2036
|
+
matchRoute,
|
|
2037
|
+
routesById,
|
|
2038
|
+
options,
|
|
2039
|
+
history,
|
|
2040
|
+
load,
|
|
2041
|
+
buildLocation,
|
|
2042
|
+
subscribe: router.subscribe,
|
|
2043
|
+
resetNextScrollRef,
|
|
2044
|
+
injectedHtmlRef,
|
|
2045
|
+
injectHtml,
|
|
2046
|
+
dehydrateData,
|
|
2047
|
+
hydrateData
|
|
2048
|
+
};
|
|
2049
|
+
return /*#__PURE__*/React.createElement(routerContext.Provider, {
|
|
2050
|
+
value: routerContextValue
|
|
2051
|
+
}, /*#__PURE__*/React.createElement(Matches, null));
|
|
2751
2052
|
}
|
|
2752
|
-
function
|
|
2753
|
-
|
|
2754
|
-
warning(!value, 'useRouter must be used inside a <Router> component!');
|
|
2755
|
-
useRouterSubscription(value.router);
|
|
2756
|
-
return value.router;
|
|
2053
|
+
function getRouteMatch(state, id) {
|
|
2054
|
+
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
2757
2055
|
}
|
|
2758
|
-
function
|
|
2759
|
-
|
|
2056
|
+
function useRouterState(opts) {
|
|
2057
|
+
const {
|
|
2058
|
+
state
|
|
2059
|
+
} = useRouter();
|
|
2060
|
+
// return useStore(router.__store, opts?.select as any)
|
|
2061
|
+
return opts?.select ? opts.select(state) : state;
|
|
2760
2062
|
}
|
|
2761
|
-
function
|
|
2762
|
-
const
|
|
2763
|
-
|
|
2063
|
+
function useRouter() {
|
|
2064
|
+
const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext;
|
|
2065
|
+
const value = React.useContext(resolvedContext);
|
|
2066
|
+
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
2067
|
+
return value;
|
|
2764
2068
|
}
|
|
2765
|
-
function useNearestMatch() {
|
|
2766
|
-
var _useMatches2;
|
|
2767
2069
|
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2070
|
+
function defer(_promise) {
|
|
2071
|
+
const promise = _promise;
|
|
2072
|
+
if (!promise.__deferredState) {
|
|
2073
|
+
promise.__deferredState = {
|
|
2074
|
+
uid: Math.random().toString(36).slice(2),
|
|
2075
|
+
status: 'pending'
|
|
2076
|
+
};
|
|
2077
|
+
const state = promise.__deferredState;
|
|
2078
|
+
promise.then(data => {
|
|
2079
|
+
state.status = 'success';
|
|
2080
|
+
state.data = data;
|
|
2081
|
+
}).catch(error => {
|
|
2082
|
+
state.status = 'error';
|
|
2083
|
+
state.error = error;
|
|
2084
|
+
});
|
|
2085
|
+
}
|
|
2086
|
+
return promise;
|
|
2771
2087
|
}
|
|
2772
|
-
function
|
|
2773
|
-
|
|
2774
|
-
return router.useRoute(routeId);
|
|
2088
|
+
function isDehydratedDeferred(obj) {
|
|
2089
|
+
return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
|
|
2775
2090
|
}
|
|
2776
|
-
|
|
2091
|
+
|
|
2092
|
+
function useAwaited({
|
|
2093
|
+
promise
|
|
2094
|
+
}) {
|
|
2777
2095
|
const router = useRouter();
|
|
2778
|
-
|
|
2096
|
+
let state = promise.__deferredState;
|
|
2097
|
+
const key = `__TSR__DEFERRED__${state.uid}`;
|
|
2098
|
+
if (isDehydratedDeferred(promise)) {
|
|
2099
|
+
state = router.hydrateData(key);
|
|
2100
|
+
promise = Promise.resolve(state.data);
|
|
2101
|
+
promise.__deferredState = state;
|
|
2102
|
+
}
|
|
2103
|
+
if (state.status === 'pending') {
|
|
2104
|
+
throw promise;
|
|
2105
|
+
}
|
|
2106
|
+
if (state.status === 'error') {
|
|
2107
|
+
throw state.error;
|
|
2108
|
+
}
|
|
2109
|
+
router.dehydrateData(key, state);
|
|
2110
|
+
return [state.data];
|
|
2779
2111
|
}
|
|
2780
|
-
function
|
|
2781
|
-
const
|
|
2782
|
-
return
|
|
2112
|
+
function Await(props) {
|
|
2113
|
+
const awaited = useAwaited(props);
|
|
2114
|
+
return props.children(...awaited);
|
|
2783
2115
|
}
|
|
2784
|
-
function Outlet() {
|
|
2785
|
-
var _ref3, _match$__$pendingComp, _match$__$errorCompon;
|
|
2786
|
-
|
|
2787
|
-
const router = useRouter();
|
|
2788
|
-
const matches = useMatches().slice(1);
|
|
2789
|
-
const match = matches[0];
|
|
2790
|
-
const defaultPending = React.useCallback(() => null, []);
|
|
2791
2116
|
|
|
2792
|
-
|
|
2793
|
-
|
|
2117
|
+
class FileRoute {
|
|
2118
|
+
constructor(path) {
|
|
2119
|
+
this.path = path;
|
|
2794
2120
|
}
|
|
2121
|
+
createRoute = options => {
|
|
2122
|
+
const route = new Route(options);
|
|
2123
|
+
route.isRoot = false;
|
|
2124
|
+
return route;
|
|
2125
|
+
};
|
|
2126
|
+
}
|
|
2795
2127
|
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
fallback: /*#__PURE__*/React.createElement(PendingComponent, null)
|
|
2802
|
-
}, /*#__PURE__*/React.createElement(CatchBoundary, {
|
|
2803
|
-
errorComponent: errorComponent
|
|
2804
|
-
}, (() => {
|
|
2805
|
-
if (match.status === 'error') {
|
|
2806
|
-
throw match.error;
|
|
2128
|
+
function lazyRouteComponent(importer, exportName) {
|
|
2129
|
+
let loadPromise;
|
|
2130
|
+
const load = () => {
|
|
2131
|
+
if (!loadPromise) {
|
|
2132
|
+
loadPromise = importer();
|
|
2807
2133
|
}
|
|
2134
|
+
return loadPromise;
|
|
2135
|
+
};
|
|
2136
|
+
const lazyComp = /*#__PURE__*/React.lazy(async () => {
|
|
2137
|
+
const moduleExports = await load();
|
|
2138
|
+
const comp = moduleExports[exportName ?? 'default'];
|
|
2139
|
+
return {
|
|
2140
|
+
default: comp
|
|
2141
|
+
};
|
|
2142
|
+
});
|
|
2143
|
+
lazyComp.preload = load;
|
|
2144
|
+
return lazyComp;
|
|
2145
|
+
}
|
|
2808
2146
|
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2147
|
+
function _extends() {
|
|
2148
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
2149
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
2150
|
+
var source = arguments[i];
|
|
2151
|
+
for (var key in source) {
|
|
2152
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
2153
|
+
target[key] = source[key];
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2813
2156
|
}
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
})())));
|
|
2157
|
+
return target;
|
|
2158
|
+
};
|
|
2159
|
+
return _extends.apply(this, arguments);
|
|
2818
2160
|
}
|
|
2819
2161
|
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2162
|
+
function useLinkProps(options) {
|
|
2163
|
+
const {
|
|
2164
|
+
buildLink
|
|
2165
|
+
} = useRouter();
|
|
2166
|
+
const match = useMatch({
|
|
2167
|
+
strict: false
|
|
2168
|
+
});
|
|
2169
|
+
const {
|
|
2170
|
+
// custom props
|
|
2171
|
+
type,
|
|
2172
|
+
children,
|
|
2173
|
+
target,
|
|
2174
|
+
activeProps = () => ({
|
|
2175
|
+
className: 'active'
|
|
2176
|
+
}),
|
|
2177
|
+
inactiveProps = () => ({}),
|
|
2178
|
+
activeOptions,
|
|
2179
|
+
disabled,
|
|
2180
|
+
hash,
|
|
2181
|
+
search,
|
|
2182
|
+
params,
|
|
2183
|
+
to,
|
|
2184
|
+
state,
|
|
2185
|
+
mask,
|
|
2186
|
+
preload,
|
|
2187
|
+
preloadDelay,
|
|
2188
|
+
replace,
|
|
2189
|
+
startTransition,
|
|
2190
|
+
resetScroll,
|
|
2191
|
+
// element props
|
|
2192
|
+
style,
|
|
2193
|
+
className,
|
|
2194
|
+
onClick,
|
|
2195
|
+
onFocus,
|
|
2196
|
+
onMouseEnter,
|
|
2197
|
+
onMouseLeave,
|
|
2198
|
+
onTouchStart,
|
|
2199
|
+
...rest
|
|
2200
|
+
} = options;
|
|
2201
|
+
const linkInfo = buildLink({
|
|
2202
|
+
from: options.to ? match.pathname : undefined,
|
|
2203
|
+
...options
|
|
2204
|
+
});
|
|
2205
|
+
if (linkInfo.type === 'external') {
|
|
2206
|
+
const {
|
|
2207
|
+
href
|
|
2208
|
+
} = linkInfo;
|
|
2209
|
+
return {
|
|
2210
|
+
href
|
|
2825
2211
|
};
|
|
2826
2212
|
}
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2213
|
+
const {
|
|
2214
|
+
handleClick,
|
|
2215
|
+
handleFocus,
|
|
2216
|
+
handleEnter,
|
|
2217
|
+
handleLeave,
|
|
2218
|
+
handleTouchStart,
|
|
2219
|
+
isActive,
|
|
2220
|
+
next
|
|
2221
|
+
} = linkInfo;
|
|
2222
|
+
const composeHandlers = handlers => e => {
|
|
2223
|
+
if (e.persist) e.persist();
|
|
2224
|
+
handlers.filter(Boolean).forEach(handler => {
|
|
2225
|
+
if (e.defaultPrevented) return;
|
|
2226
|
+
handler(e);
|
|
2833
2227
|
});
|
|
2834
|
-
}
|
|
2835
|
-
|
|
2836
|
-
render() {
|
|
2837
|
-
var _this$props$errorComp;
|
|
2838
|
-
|
|
2839
|
-
const errorComponent = (_this$props$errorComp = this.props.errorComponent) != null ? _this$props$errorComp : DefaultErrorBoundary;
|
|
2840
|
-
|
|
2841
|
-
if (this.state.error) {
|
|
2842
|
-
return /*#__PURE__*/React.createElement(errorComponent, this.state);
|
|
2843
|
-
}
|
|
2844
|
-
|
|
2845
|
-
return this.props.children;
|
|
2846
|
-
}
|
|
2228
|
+
};
|
|
2847
2229
|
|
|
2848
|
-
|
|
2230
|
+
// Get the active props
|
|
2231
|
+
const resolvedActiveProps = isActive ? functionalUpdate(activeProps, {}) ?? {} : {};
|
|
2849
2232
|
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2233
|
+
// Get the inactive props
|
|
2234
|
+
const resolvedInactiveProps = isActive ? {} : functionalUpdate(inactiveProps, {}) ?? {};
|
|
2235
|
+
return {
|
|
2236
|
+
...resolvedActiveProps,
|
|
2237
|
+
...resolvedInactiveProps,
|
|
2238
|
+
...rest,
|
|
2239
|
+
href: disabled ? undefined : next.maskedLocation ? next.maskedLocation.href : next.href,
|
|
2240
|
+
onClick: composeHandlers([onClick, handleClick]),
|
|
2241
|
+
onFocus: composeHandlers([onFocus, handleFocus]),
|
|
2242
|
+
onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
|
|
2243
|
+
onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),
|
|
2244
|
+
onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),
|
|
2245
|
+
target,
|
|
2860
2246
|
style: {
|
|
2861
|
-
|
|
2247
|
+
...style,
|
|
2248
|
+
...resolvedActiveProps.style,
|
|
2249
|
+
...resolvedInactiveProps.style
|
|
2250
|
+
},
|
|
2251
|
+
className: [className, resolvedActiveProps.className, resolvedInactiveProps.className].filter(Boolean).join(' ') || undefined,
|
|
2252
|
+
...(disabled ? {
|
|
2253
|
+
role: 'link',
|
|
2254
|
+
'aria-disabled': true
|
|
2255
|
+
} : undefined),
|
|
2256
|
+
['data-status']: isActive ? 'active' : undefined
|
|
2257
|
+
};
|
|
2258
|
+
}
|
|
2259
|
+
const Link = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
2260
|
+
const linkProps = useLinkProps(props);
|
|
2261
|
+
return /*#__PURE__*/React.createElement("a", _extends({
|
|
2262
|
+
ref: ref
|
|
2263
|
+
}, linkProps, {
|
|
2264
|
+
children: typeof props.children === 'function' ? props.children({
|
|
2265
|
+
isActive: linkProps['data-status'] === 'active'
|
|
2266
|
+
}) : props.children
|
|
2267
|
+
}));
|
|
2268
|
+
});
|
|
2269
|
+
|
|
2270
|
+
const useLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
2271
|
+
const windowKey = 'window';
|
|
2272
|
+
const delimiter = '___';
|
|
2273
|
+
let weakScrolledElements = new WeakSet();
|
|
2274
|
+
let cache;
|
|
2275
|
+
const sessionsStorage = typeof window !== 'undefined' && window.sessionStorage;
|
|
2276
|
+
const defaultGetKey = location => location.state.key;
|
|
2277
|
+
function useScrollRestoration(options) {
|
|
2278
|
+
const {
|
|
2279
|
+
state,
|
|
2280
|
+
subscribe,
|
|
2281
|
+
resetNextScrollRef
|
|
2282
|
+
} = useRouter();
|
|
2283
|
+
useLayoutEffect(() => {
|
|
2284
|
+
const getKey = options?.getKey || defaultGetKey;
|
|
2285
|
+
if (sessionsStorage) {
|
|
2286
|
+
if (!cache) {
|
|
2287
|
+
cache = (() => {
|
|
2288
|
+
const storageKey = 'tsr-scroll-restoration-v2';
|
|
2289
|
+
const state = JSON.parse(window.sessionStorage.getItem(storageKey) || 'null') || {
|
|
2290
|
+
cached: {},
|
|
2291
|
+
next: {}
|
|
2292
|
+
};
|
|
2293
|
+
return {
|
|
2294
|
+
state,
|
|
2295
|
+
set: updater => {
|
|
2296
|
+
cache.state = functionalUpdate(updater, cache.state);
|
|
2297
|
+
window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state));
|
|
2298
|
+
}
|
|
2299
|
+
};
|
|
2300
|
+
})();
|
|
2301
|
+
}
|
|
2862
2302
|
}
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2303
|
+
const {
|
|
2304
|
+
history
|
|
2305
|
+
} = window;
|
|
2306
|
+
if (history.scrollRestoration) {
|
|
2307
|
+
history.scrollRestoration = 'manual';
|
|
2866
2308
|
}
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2309
|
+
const onScroll = event => {
|
|
2310
|
+
if (weakScrolledElements.has(event.target)) return;
|
|
2311
|
+
weakScrolledElements.add(event.target);
|
|
2312
|
+
const elementSelector = event.target === document || event.target === window ? windowKey : getCssSelector(event.target);
|
|
2313
|
+
if (!cache.state.next[elementSelector]) {
|
|
2314
|
+
cache.set(c => ({
|
|
2315
|
+
...c,
|
|
2316
|
+
next: {
|
|
2317
|
+
...c.next,
|
|
2318
|
+
[elementSelector]: {
|
|
2319
|
+
scrollX: NaN,
|
|
2320
|
+
scrollY: NaN
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2323
|
+
}));
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
const getCssSelector = el => {
|
|
2327
|
+
let path = [],
|
|
2328
|
+
parent;
|
|
2329
|
+
while (parent = el.parentNode) {
|
|
2330
|
+
path.unshift(`${el.tagName}:nth-child(${[].indexOf.call(parent.children, el) + 1})`);
|
|
2331
|
+
el = parent;
|
|
2332
|
+
}
|
|
2333
|
+
return `${path.join(' > ')}`.toLowerCase();
|
|
2334
|
+
};
|
|
2335
|
+
if (typeof document !== 'undefined') {
|
|
2336
|
+
document.addEventListener('scroll', onScroll, true);
|
|
2874
2337
|
}
|
|
2875
|
-
|
|
2338
|
+
const unsubOnBeforeLoad = subscribe('onBeforeLoad', event => {
|
|
2339
|
+
if (event.pathChanged) {
|
|
2340
|
+
const restoreKey = getKey(event.fromLocation);
|
|
2341
|
+
for (const elementSelector in cache.state.next) {
|
|
2342
|
+
const entry = cache.state.next[elementSelector];
|
|
2343
|
+
if (elementSelector === windowKey) {
|
|
2344
|
+
entry.scrollX = window.scrollX || 0;
|
|
2345
|
+
entry.scrollY = window.scrollY || 0;
|
|
2346
|
+
} else if (elementSelector) {
|
|
2347
|
+
const element = document.querySelector(elementSelector);
|
|
2348
|
+
entry.scrollX = element?.scrollLeft || 0;
|
|
2349
|
+
entry.scrollY = element?.scrollTop || 0;
|
|
2350
|
+
}
|
|
2351
|
+
cache.set(c => {
|
|
2352
|
+
const next = {
|
|
2353
|
+
...c.next
|
|
2354
|
+
};
|
|
2355
|
+
delete next[elementSelector];
|
|
2356
|
+
return {
|
|
2357
|
+
...c,
|
|
2358
|
+
next,
|
|
2359
|
+
cached: {
|
|
2360
|
+
...c.cached,
|
|
2361
|
+
[[restoreKey, elementSelector].join(delimiter)]: entry
|
|
2362
|
+
}
|
|
2363
|
+
};
|
|
2364
|
+
});
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
});
|
|
2368
|
+
const unsubOnResolved = subscribe('onResolved', event => {
|
|
2369
|
+
if (event.pathChanged) {
|
|
2370
|
+
if (!resetNextScrollRef.current) {
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
resetNextScrollRef.current = true;
|
|
2374
|
+
const getKey = options?.getKey || defaultGetKey;
|
|
2375
|
+
const restoreKey = getKey(event.toLocation);
|
|
2376
|
+
let windowRestored = false;
|
|
2377
|
+
for (const cacheKey in cache.state.cached) {
|
|
2378
|
+
const entry = cache.state.cached[cacheKey];
|
|
2379
|
+
const [key, elementSelector] = cacheKey.split(delimiter);
|
|
2380
|
+
if (key === restoreKey) {
|
|
2381
|
+
if (elementSelector === windowKey) {
|
|
2382
|
+
windowRestored = true;
|
|
2383
|
+
window.scrollTo(entry.scrollX, entry.scrollY);
|
|
2384
|
+
} else if (elementSelector) {
|
|
2385
|
+
const element = document.querySelector(elementSelector);
|
|
2386
|
+
if (element) {
|
|
2387
|
+
element.scrollLeft = entry.scrollX;
|
|
2388
|
+
element.scrollTop = entry.scrollY;
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
if (!windowRestored) {
|
|
2394
|
+
window.scrollTo(0, 0);
|
|
2395
|
+
}
|
|
2396
|
+
cache.set(c => ({
|
|
2397
|
+
...c,
|
|
2398
|
+
next: {}
|
|
2399
|
+
}));
|
|
2400
|
+
weakScrolledElements = new WeakSet();
|
|
2401
|
+
}
|
|
2402
|
+
});
|
|
2403
|
+
return () => {
|
|
2404
|
+
document.removeEventListener('scroll', onScroll);
|
|
2405
|
+
unsubOnBeforeLoad();
|
|
2406
|
+
unsubOnResolved();
|
|
2407
|
+
};
|
|
2408
|
+
}, []);
|
|
2876
2409
|
}
|
|
2877
|
-
function
|
|
2878
|
-
|
|
2410
|
+
function ScrollRestoration(props) {
|
|
2411
|
+
useScrollRestoration(props);
|
|
2412
|
+
return null;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
function useBlocker(message, condition = true) {
|
|
2416
|
+
const {
|
|
2417
|
+
history
|
|
2418
|
+
} = useRouter();
|
|
2879
2419
|
React.useEffect(() => {
|
|
2880
|
-
if (!
|
|
2881
|
-
let unblock =
|
|
2420
|
+
if (!condition) return;
|
|
2421
|
+
let unblock = history.block((retry, cancel) => {
|
|
2882
2422
|
if (window.confirm(message)) {
|
|
2883
2423
|
unblock();
|
|
2884
|
-
|
|
2885
|
-
} else {
|
|
2886
|
-
router.location.pathname = window.location.pathname;
|
|
2424
|
+
retry();
|
|
2887
2425
|
}
|
|
2888
2426
|
});
|
|
2889
2427
|
return unblock;
|
|
2890
|
-
}
|
|
2428
|
+
});
|
|
2429
|
+
}
|
|
2430
|
+
function Block({
|
|
2431
|
+
message,
|
|
2432
|
+
condition,
|
|
2433
|
+
children
|
|
2434
|
+
}) {
|
|
2435
|
+
useBlocker(message, condition);
|
|
2436
|
+
return children ?? null;
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
function useNavigate(defaultOpts) {
|
|
2440
|
+
const {
|
|
2441
|
+
navigate
|
|
2442
|
+
} = useRouter();
|
|
2443
|
+
const match = useMatch({
|
|
2444
|
+
strict: false
|
|
2445
|
+
});
|
|
2446
|
+
return React.useCallback(opts => {
|
|
2447
|
+
return navigate({
|
|
2448
|
+
from: opts?.to ? match.pathname : undefined,
|
|
2449
|
+
...defaultOpts,
|
|
2450
|
+
...opts
|
|
2451
|
+
});
|
|
2452
|
+
}, []);
|
|
2891
2453
|
}
|
|
2892
|
-
function
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2454
|
+
function typedNavigate(navigate) {
|
|
2455
|
+
return navigate;
|
|
2456
|
+
} //
|
|
2457
|
+
|
|
2458
|
+
function Navigate(props) {
|
|
2459
|
+
const {
|
|
2460
|
+
navigate
|
|
2461
|
+
} = useRouter();
|
|
2462
|
+
const match = useMatch({
|
|
2463
|
+
strict: false
|
|
2464
|
+
});
|
|
2465
|
+
useLayoutEffect$1(() => {
|
|
2466
|
+
navigate({
|
|
2467
|
+
from: props.to ? match.pathname : undefined,
|
|
2468
|
+
...props
|
|
2469
|
+
});
|
|
2470
|
+
}, []);
|
|
2471
|
+
return null;
|
|
2900
2472
|
}
|
|
2901
2473
|
|
|
2902
|
-
export {
|
|
2474
|
+
export { Await, Block, CatchBoundary, CatchBoundaryImpl, ErrorComponent, FileRoute, Link, Match, MatchRoute, Matches, Navigate, Outlet, PathParamError, RootRoute, Route, Router, RouterProvider, ScrollRestoration, SearchParamError, cleanPath, componentTypes, createRouteMask, decode, deepEqual, defaultParseSearch, defaultStringifySearch, defer, encode, escapeJSON, functionalUpdate, getInitialRouterState, getRouteMatch, interpolatePath, isDehydratedDeferred, isPlainObject, isRedirect, isServer, joinPaths, last, lazyFn, lazyRouteComponent, matchByPath, matchPathname, matchesContext, parsePathname, parseSearchWith, pick, redirect, replaceEqualDeep, resolvePath, rootRouteId, rootRouteWithContext, routerContext, shallow, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, typedNavigate, useAwaited, useBlocker, useLayoutEffect$1 as useLayoutEffect, useLinkProps, useLoaderData, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useRouteContext, useRouter, useRouterState, useScrollRestoration, useSearch, useStableCallback };
|
|
2903
2475
|
//# sourceMappingURL=index.js.map
|