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