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