@tanstack/router-core 0.0.1-beta.4 → 0.0.1-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/{packages/router-core/src/index.js → index.js} +25 -8
- package/build/cjs/{packages/router-core/src/index.js.map → index.js.map} +1 -1
- package/build/cjs/{packages/router-core/src/path.js → path.js} +19 -43
- package/build/cjs/path.js.map +1 -0
- package/build/cjs/{packages/router-core/src/qss.js → qss.js} +8 -13
- package/build/cjs/qss.js.map +1 -0
- package/build/cjs/route.js +155 -0
- package/build/cjs/route.js.map +1 -0
- package/build/cjs/{packages/router-core/src/routeConfig.js → routeConfig.js} +14 -13
- package/build/cjs/routeConfig.js.map +1 -0
- package/build/cjs/routeMatch.js +242 -0
- package/build/cjs/routeMatch.js.map +1 -0
- package/build/cjs/router.js +807 -0
- package/build/cjs/router.js.map +1 -0
- package/build/cjs/{packages/router-core/src/searchParams.js → searchParams.js} +10 -12
- package/build/cjs/searchParams.js.map +1 -0
- package/build/cjs/sharedClone.js +122 -0
- package/build/cjs/sharedClone.js.map +1 -0
- package/build/cjs/utils.js +47 -0
- package/build/cjs/utils.js.map +1 -0
- package/build/esm/index.js +890 -1739
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +59 -49
- package/build/stats-react.json +196 -178
- package/build/types/index.d.ts +287 -283
- package/build/umd/index.development.js +1233 -922
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +4 -2
- package/src/frameworks.ts +2 -2
- package/src/index.ts +1 -1
- package/src/link.ts +86 -43
- package/src/path.ts +12 -8
- package/src/route.ts +170 -158
- package/src/routeConfig.ts +105 -77
- package/src/routeInfo.ts +26 -8
- package/src/routeMatch.ts +204 -217
- package/src/router.ts +680 -503
- package/src/sharedClone.ts +118 -0
- package/src/utils.ts +14 -72
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -33
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
- package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js +0 -33
- package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js.map +0 -1
- package/build/cjs/node_modules/history/index.js +0 -815
- package/build/cjs/node_modules/history/index.js.map +0 -1
- package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +0 -30
- package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +0 -1
- package/build/cjs/packages/router-core/src/path.js.map +0 -1
- package/build/cjs/packages/router-core/src/qss.js.map +0 -1
- package/build/cjs/packages/router-core/src/route.js +0 -161
- package/build/cjs/packages/router-core/src/route.js.map +0 -1
- package/build/cjs/packages/router-core/src/routeConfig.js.map +0 -1
- package/build/cjs/packages/router-core/src/routeMatch.js +0 -266
- package/build/cjs/packages/router-core/src/routeMatch.js.map +0 -1
- package/build/cjs/packages/router-core/src/router.js +0 -789
- package/build/cjs/packages/router-core/src/router.js.map +0 -1
- package/build/cjs/packages/router-core/src/searchParams.js.map +0 -1
- package/build/cjs/packages/router-core/src/utils.js +0 -118
- package/build/cjs/packages/router-core/src/utils.js.map +0 -1
package/build/esm/index.js
CHANGED
|
@@ -8,901 +8,11 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
for (var key in source) {
|
|
17
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
18
|
-
target[key] = source[key];
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return target;
|
|
24
|
-
};
|
|
25
|
-
return _extends$1.apply(this, arguments);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Actions represent the type of change to a location value.
|
|
30
|
-
*
|
|
31
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#action
|
|
32
|
-
*/
|
|
33
|
-
var Action;
|
|
34
|
-
|
|
35
|
-
(function (Action) {
|
|
36
|
-
/**
|
|
37
|
-
* A POP indicates a change to an arbitrary index in the history stack, such
|
|
38
|
-
* as a back or forward navigation. It does not describe the direction of the
|
|
39
|
-
* navigation, only that the current index changed.
|
|
40
|
-
*
|
|
41
|
-
* Note: This is the default action for newly created history objects.
|
|
42
|
-
*/
|
|
43
|
-
Action["Pop"] = "POP";
|
|
44
|
-
/**
|
|
45
|
-
* A PUSH indicates a new entry being added to the history stack, such as when
|
|
46
|
-
* a link is clicked and a new page loads. When this happens, all subsequent
|
|
47
|
-
* entries in the stack are lost.
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
|
-
Action["Push"] = "PUSH";
|
|
51
|
-
/**
|
|
52
|
-
* A REPLACE indicates the entry at the current index in the history stack
|
|
53
|
-
* being replaced by a new one.
|
|
54
|
-
*/
|
|
55
|
-
|
|
56
|
-
Action["Replace"] = "REPLACE";
|
|
57
|
-
})(Action || (Action = {}));
|
|
58
|
-
|
|
59
|
-
var readOnly = process.env.NODE_ENV !== "production" ? function (obj) {
|
|
60
|
-
return Object.freeze(obj);
|
|
61
|
-
} : function (obj) {
|
|
62
|
-
return obj;
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
function warning$1(cond, message) {
|
|
66
|
-
if (!cond) {
|
|
67
|
-
// eslint-disable-next-line no-console
|
|
68
|
-
if (typeof console !== 'undefined') console.warn(message);
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
// Welcome to debugging history!
|
|
72
|
-
//
|
|
73
|
-
// This error is thrown as a convenience so you can more easily
|
|
74
|
-
// find the source for a warning that appears in the console by
|
|
75
|
-
// enabling "pause on exceptions" in your JavaScript debugger.
|
|
76
|
-
throw new Error(message); // eslint-disable-next-line no-empty
|
|
77
|
-
} catch (e) {}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
var BeforeUnloadEventType = 'beforeunload';
|
|
82
|
-
var HashChangeEventType = 'hashchange';
|
|
83
|
-
var PopStateEventType = 'popstate';
|
|
84
|
-
/**
|
|
85
|
-
* Browser history stores the location in regular URLs. This is the standard for
|
|
86
|
-
* most web apps, but it requires some configuration on the server to ensure you
|
|
87
|
-
* serve the same app at multiple URLs.
|
|
88
|
-
*
|
|
89
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
function createBrowserHistory(options) {
|
|
93
|
-
if (options === void 0) {
|
|
94
|
-
options = {};
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
var _options = options,
|
|
98
|
-
_options$window = _options.window,
|
|
99
|
-
window = _options$window === void 0 ? document.defaultView : _options$window;
|
|
100
|
-
var globalHistory = window.history;
|
|
101
|
-
|
|
102
|
-
function getIndexAndLocation() {
|
|
103
|
-
var _window$location = window.location,
|
|
104
|
-
pathname = _window$location.pathname,
|
|
105
|
-
search = _window$location.search,
|
|
106
|
-
hash = _window$location.hash;
|
|
107
|
-
var state = globalHistory.state || {};
|
|
108
|
-
return [state.idx, readOnly({
|
|
109
|
-
pathname: pathname,
|
|
110
|
-
search: search,
|
|
111
|
-
hash: hash,
|
|
112
|
-
state: state.usr || null,
|
|
113
|
-
key: state.key || 'default'
|
|
114
|
-
})];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
var blockedPopTx = null;
|
|
118
|
-
|
|
119
|
-
function handlePop() {
|
|
120
|
-
if (blockedPopTx) {
|
|
121
|
-
blockers.call(blockedPopTx);
|
|
122
|
-
blockedPopTx = null;
|
|
123
|
-
} else {
|
|
124
|
-
var nextAction = Action.Pop;
|
|
125
|
-
|
|
126
|
-
var _getIndexAndLocation = getIndexAndLocation(),
|
|
127
|
-
nextIndex = _getIndexAndLocation[0],
|
|
128
|
-
nextLocation = _getIndexAndLocation[1];
|
|
129
|
-
|
|
130
|
-
if (blockers.length) {
|
|
131
|
-
if (nextIndex != null) {
|
|
132
|
-
var delta = index - nextIndex;
|
|
133
|
-
|
|
134
|
-
if (delta) {
|
|
135
|
-
// Revert the POP
|
|
136
|
-
blockedPopTx = {
|
|
137
|
-
action: nextAction,
|
|
138
|
-
location: nextLocation,
|
|
139
|
-
retry: function retry() {
|
|
140
|
-
go(delta * -1);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
go(delta);
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
// Trying to POP to a location with no index. We did not create
|
|
147
|
-
// this location, so we can't effectively block the navigation.
|
|
148
|
-
process.env.NODE_ENV !== "production" ? warning$1(false, // TODO: Write up a doc that explains our blocking strategy in
|
|
149
|
-
// detail and link to it here so people can understand better what
|
|
150
|
-
// is going on and how to avoid it.
|
|
151
|
-
"You are trying to block a POP navigation to a location that was not " + "created by the history library. The block will fail silently in " + "production, but in general you should do all navigation with the " + "history library (instead of using window.history.pushState directly) " + "to avoid this situation.") : void 0;
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
applyTx(nextAction);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
window.addEventListener(PopStateEventType, handlePop);
|
|
160
|
-
var action = Action.Pop;
|
|
161
|
-
|
|
162
|
-
var _getIndexAndLocation2 = getIndexAndLocation(),
|
|
163
|
-
index = _getIndexAndLocation2[0],
|
|
164
|
-
location = _getIndexAndLocation2[1];
|
|
165
|
-
|
|
166
|
-
var listeners = createEvents();
|
|
167
|
-
var blockers = createEvents();
|
|
168
|
-
|
|
169
|
-
if (index == null) {
|
|
170
|
-
index = 0;
|
|
171
|
-
globalHistory.replaceState(_extends$1({}, globalHistory.state, {
|
|
172
|
-
idx: index
|
|
173
|
-
}), '');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function createHref(to) {
|
|
177
|
-
return typeof to === 'string' ? to : createPath(to);
|
|
178
|
-
} // state defaults to `null` because `window.history.state` does
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
function getNextLocation(to, state) {
|
|
182
|
-
if (state === void 0) {
|
|
183
|
-
state = null;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return readOnly(_extends$1({
|
|
187
|
-
pathname: location.pathname,
|
|
188
|
-
hash: '',
|
|
189
|
-
search: ''
|
|
190
|
-
}, typeof to === 'string' ? parsePath(to) : to, {
|
|
191
|
-
state: state,
|
|
192
|
-
key: createKey()
|
|
193
|
-
}));
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
function getHistoryStateAndUrl(nextLocation, index) {
|
|
197
|
-
return [{
|
|
198
|
-
usr: nextLocation.state,
|
|
199
|
-
key: nextLocation.key,
|
|
200
|
-
idx: index
|
|
201
|
-
}, createHref(nextLocation)];
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function allowTx(action, location, retry) {
|
|
205
|
-
return !blockers.length || (blockers.call({
|
|
206
|
-
action: action,
|
|
207
|
-
location: location,
|
|
208
|
-
retry: retry
|
|
209
|
-
}), false);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function applyTx(nextAction) {
|
|
213
|
-
action = nextAction;
|
|
214
|
-
|
|
215
|
-
var _getIndexAndLocation3 = getIndexAndLocation();
|
|
216
|
-
|
|
217
|
-
index = _getIndexAndLocation3[0];
|
|
218
|
-
location = _getIndexAndLocation3[1];
|
|
219
|
-
listeners.call({
|
|
220
|
-
action: action,
|
|
221
|
-
location: location
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function push(to, state) {
|
|
226
|
-
var nextAction = Action.Push;
|
|
227
|
-
var nextLocation = getNextLocation(to, state);
|
|
228
|
-
|
|
229
|
-
function retry() {
|
|
230
|
-
push(to, state);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
234
|
-
var _getHistoryStateAndUr = getHistoryStateAndUrl(nextLocation, index + 1),
|
|
235
|
-
historyState = _getHistoryStateAndUr[0],
|
|
236
|
-
url = _getHistoryStateAndUr[1]; // TODO: Support forced reloading
|
|
237
|
-
// try...catch because iOS limits us to 100 pushState calls :/
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
globalHistory.pushState(historyState, '', url);
|
|
242
|
-
} catch (error) {
|
|
243
|
-
// They are going to lose state here, but there is no real
|
|
244
|
-
// way to warn them about it since the page will refresh...
|
|
245
|
-
window.location.assign(url);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
applyTx(nextAction);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function replace(to, state) {
|
|
253
|
-
var nextAction = Action.Replace;
|
|
254
|
-
var nextLocation = getNextLocation(to, state);
|
|
255
|
-
|
|
256
|
-
function retry() {
|
|
257
|
-
replace(to, state);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
261
|
-
var _getHistoryStateAndUr2 = getHistoryStateAndUrl(nextLocation, index),
|
|
262
|
-
historyState = _getHistoryStateAndUr2[0],
|
|
263
|
-
url = _getHistoryStateAndUr2[1]; // TODO: Support forced reloading
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
globalHistory.replaceState(historyState, '', url);
|
|
267
|
-
applyTx(nextAction);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
function go(delta) {
|
|
272
|
-
globalHistory.go(delta);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
var history = {
|
|
276
|
-
get action() {
|
|
277
|
-
return action;
|
|
278
|
-
},
|
|
279
|
-
|
|
280
|
-
get location() {
|
|
281
|
-
return location;
|
|
282
|
-
},
|
|
283
|
-
|
|
284
|
-
createHref: createHref,
|
|
285
|
-
push: push,
|
|
286
|
-
replace: replace,
|
|
287
|
-
go: go,
|
|
288
|
-
back: function back() {
|
|
289
|
-
go(-1);
|
|
290
|
-
},
|
|
291
|
-
forward: function forward() {
|
|
292
|
-
go(1);
|
|
293
|
-
},
|
|
294
|
-
listen: function listen(listener) {
|
|
295
|
-
return listeners.push(listener);
|
|
296
|
-
},
|
|
297
|
-
block: function block(blocker) {
|
|
298
|
-
var unblock = blockers.push(blocker);
|
|
299
|
-
|
|
300
|
-
if (blockers.length === 1) {
|
|
301
|
-
window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
return function () {
|
|
305
|
-
unblock(); // Remove the beforeunload listener so the document may
|
|
306
|
-
// still be salvageable in the pagehide event.
|
|
307
|
-
// See https://html.spec.whatwg.org/#unloading-documents
|
|
308
|
-
|
|
309
|
-
if (!blockers.length) {
|
|
310
|
-
window.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
return history;
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Hash history stores the location in window.location.hash. This makes it ideal
|
|
319
|
-
* for situations where you don't want to send the location to the server for
|
|
320
|
-
* some reason, either because you do cannot configure it or the URL space is
|
|
321
|
-
* reserved for something else.
|
|
322
|
-
*
|
|
323
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory
|
|
324
|
-
*/
|
|
325
|
-
|
|
326
|
-
function createHashHistory(options) {
|
|
327
|
-
if (options === void 0) {
|
|
328
|
-
options = {};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
var _options2 = options,
|
|
332
|
-
_options2$window = _options2.window,
|
|
333
|
-
window = _options2$window === void 0 ? document.defaultView : _options2$window;
|
|
334
|
-
var globalHistory = window.history;
|
|
335
|
-
|
|
336
|
-
function getIndexAndLocation() {
|
|
337
|
-
var _parsePath = parsePath(window.location.hash.substr(1)),
|
|
338
|
-
_parsePath$pathname = _parsePath.pathname,
|
|
339
|
-
pathname = _parsePath$pathname === void 0 ? '/' : _parsePath$pathname,
|
|
340
|
-
_parsePath$search = _parsePath.search,
|
|
341
|
-
search = _parsePath$search === void 0 ? '' : _parsePath$search,
|
|
342
|
-
_parsePath$hash = _parsePath.hash,
|
|
343
|
-
hash = _parsePath$hash === void 0 ? '' : _parsePath$hash;
|
|
344
|
-
|
|
345
|
-
var state = globalHistory.state || {};
|
|
346
|
-
return [state.idx, readOnly({
|
|
347
|
-
pathname: pathname,
|
|
348
|
-
search: search,
|
|
349
|
-
hash: hash,
|
|
350
|
-
state: state.usr || null,
|
|
351
|
-
key: state.key || 'default'
|
|
352
|
-
})];
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
var blockedPopTx = null;
|
|
356
|
-
|
|
357
|
-
function handlePop() {
|
|
358
|
-
if (blockedPopTx) {
|
|
359
|
-
blockers.call(blockedPopTx);
|
|
360
|
-
blockedPopTx = null;
|
|
361
|
-
} else {
|
|
362
|
-
var nextAction = Action.Pop;
|
|
363
|
-
|
|
364
|
-
var _getIndexAndLocation4 = getIndexAndLocation(),
|
|
365
|
-
nextIndex = _getIndexAndLocation4[0],
|
|
366
|
-
nextLocation = _getIndexAndLocation4[1];
|
|
367
|
-
|
|
368
|
-
if (blockers.length) {
|
|
369
|
-
if (nextIndex != null) {
|
|
370
|
-
var delta = index - nextIndex;
|
|
371
|
-
|
|
372
|
-
if (delta) {
|
|
373
|
-
// Revert the POP
|
|
374
|
-
blockedPopTx = {
|
|
375
|
-
action: nextAction,
|
|
376
|
-
location: nextLocation,
|
|
377
|
-
retry: function retry() {
|
|
378
|
-
go(delta * -1);
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
go(delta);
|
|
382
|
-
}
|
|
383
|
-
} else {
|
|
384
|
-
// Trying to POP to a location with no index. We did not create
|
|
385
|
-
// this location, so we can't effectively block the navigation.
|
|
386
|
-
process.env.NODE_ENV !== "production" ? warning$1(false, // TODO: Write up a doc that explains our blocking strategy in
|
|
387
|
-
// detail and link to it here so people can understand better
|
|
388
|
-
// what is going on and how to avoid it.
|
|
389
|
-
"You are trying to block a POP navigation to a location that was not " + "created by the history library. The block will fail silently in " + "production, but in general you should do all navigation with the " + "history library (instead of using window.history.pushState directly) " + "to avoid this situation.") : void 0;
|
|
390
|
-
}
|
|
391
|
-
} else {
|
|
392
|
-
applyTx(nextAction);
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
window.addEventListener(PopStateEventType, handlePop); // popstate does not fire on hashchange in IE 11 and old (trident) Edge
|
|
398
|
-
// https://developer.mozilla.org/de/docs/Web/API/Window/popstate_event
|
|
399
|
-
|
|
400
|
-
window.addEventListener(HashChangeEventType, function () {
|
|
401
|
-
var _getIndexAndLocation5 = getIndexAndLocation(),
|
|
402
|
-
nextLocation = _getIndexAndLocation5[1]; // Ignore extraneous hashchange events.
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
if (createPath(nextLocation) !== createPath(location)) {
|
|
406
|
-
handlePop();
|
|
407
|
-
}
|
|
408
|
-
});
|
|
409
|
-
var action = Action.Pop;
|
|
410
|
-
|
|
411
|
-
var _getIndexAndLocation6 = getIndexAndLocation(),
|
|
412
|
-
index = _getIndexAndLocation6[0],
|
|
413
|
-
location = _getIndexAndLocation6[1];
|
|
414
|
-
|
|
415
|
-
var listeners = createEvents();
|
|
416
|
-
var blockers = createEvents();
|
|
417
|
-
|
|
418
|
-
if (index == null) {
|
|
419
|
-
index = 0;
|
|
420
|
-
globalHistory.replaceState(_extends$1({}, globalHistory.state, {
|
|
421
|
-
idx: index
|
|
422
|
-
}), '');
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
function getBaseHref() {
|
|
426
|
-
var base = document.querySelector('base');
|
|
427
|
-
var href = '';
|
|
428
|
-
|
|
429
|
-
if (base && base.getAttribute('href')) {
|
|
430
|
-
var url = window.location.href;
|
|
431
|
-
var hashIndex = url.indexOf('#');
|
|
432
|
-
href = hashIndex === -1 ? url : url.slice(0, hashIndex);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return href;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
function createHref(to) {
|
|
439
|
-
return getBaseHref() + '#' + (typeof to === 'string' ? to : createPath(to));
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
function getNextLocation(to, state) {
|
|
443
|
-
if (state === void 0) {
|
|
444
|
-
state = null;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
return readOnly(_extends$1({
|
|
448
|
-
pathname: location.pathname,
|
|
449
|
-
hash: '',
|
|
450
|
-
search: ''
|
|
451
|
-
}, typeof to === 'string' ? parsePath(to) : to, {
|
|
452
|
-
state: state,
|
|
453
|
-
key: createKey()
|
|
454
|
-
}));
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
function getHistoryStateAndUrl(nextLocation, index) {
|
|
458
|
-
return [{
|
|
459
|
-
usr: nextLocation.state,
|
|
460
|
-
key: nextLocation.key,
|
|
461
|
-
idx: index
|
|
462
|
-
}, createHref(nextLocation)];
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
function allowTx(action, location, retry) {
|
|
466
|
-
return !blockers.length || (blockers.call({
|
|
467
|
-
action: action,
|
|
468
|
-
location: location,
|
|
469
|
-
retry: retry
|
|
470
|
-
}), false);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
function applyTx(nextAction) {
|
|
474
|
-
action = nextAction;
|
|
475
|
-
|
|
476
|
-
var _getIndexAndLocation7 = getIndexAndLocation();
|
|
477
|
-
|
|
478
|
-
index = _getIndexAndLocation7[0];
|
|
479
|
-
location = _getIndexAndLocation7[1];
|
|
480
|
-
listeners.call({
|
|
481
|
-
action: action,
|
|
482
|
-
location: location
|
|
483
|
-
});
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
function push(to, state) {
|
|
487
|
-
var nextAction = Action.Push;
|
|
488
|
-
var nextLocation = getNextLocation(to, state);
|
|
489
|
-
|
|
490
|
-
function retry() {
|
|
491
|
-
push(to, state);
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
process.env.NODE_ENV !== "production" ? warning$1(nextLocation.pathname.charAt(0) === '/', "Relative pathnames are not supported in hash history.push(" + JSON.stringify(to) + ")") : void 0;
|
|
495
|
-
|
|
496
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
497
|
-
var _getHistoryStateAndUr3 = getHistoryStateAndUrl(nextLocation, index + 1),
|
|
498
|
-
historyState = _getHistoryStateAndUr3[0],
|
|
499
|
-
url = _getHistoryStateAndUr3[1]; // TODO: Support forced reloading
|
|
500
|
-
// try...catch because iOS limits us to 100 pushState calls :/
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
try {
|
|
504
|
-
globalHistory.pushState(historyState, '', url);
|
|
505
|
-
} catch (error) {
|
|
506
|
-
// They are going to lose state here, but there is no real
|
|
507
|
-
// way to warn them about it since the page will refresh...
|
|
508
|
-
window.location.assign(url);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
applyTx(nextAction);
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
function replace(to, state) {
|
|
516
|
-
var nextAction = Action.Replace;
|
|
517
|
-
var nextLocation = getNextLocation(to, state);
|
|
518
|
-
|
|
519
|
-
function retry() {
|
|
520
|
-
replace(to, state);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
process.env.NODE_ENV !== "production" ? warning$1(nextLocation.pathname.charAt(0) === '/', "Relative pathnames are not supported in hash history.replace(" + JSON.stringify(to) + ")") : void 0;
|
|
524
|
-
|
|
525
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
526
|
-
var _getHistoryStateAndUr4 = getHistoryStateAndUrl(nextLocation, index),
|
|
527
|
-
historyState = _getHistoryStateAndUr4[0],
|
|
528
|
-
url = _getHistoryStateAndUr4[1]; // TODO: Support forced reloading
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
globalHistory.replaceState(historyState, '', url);
|
|
532
|
-
applyTx(nextAction);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
function go(delta) {
|
|
537
|
-
globalHistory.go(delta);
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
var history = {
|
|
541
|
-
get action() {
|
|
542
|
-
return action;
|
|
543
|
-
},
|
|
544
|
-
|
|
545
|
-
get location() {
|
|
546
|
-
return location;
|
|
547
|
-
},
|
|
548
|
-
|
|
549
|
-
createHref: createHref,
|
|
550
|
-
push: push,
|
|
551
|
-
replace: replace,
|
|
552
|
-
go: go,
|
|
553
|
-
back: function back() {
|
|
554
|
-
go(-1);
|
|
555
|
-
},
|
|
556
|
-
forward: function forward() {
|
|
557
|
-
go(1);
|
|
558
|
-
},
|
|
559
|
-
listen: function listen(listener) {
|
|
560
|
-
return listeners.push(listener);
|
|
561
|
-
},
|
|
562
|
-
block: function block(blocker) {
|
|
563
|
-
var unblock = blockers.push(blocker);
|
|
564
|
-
|
|
565
|
-
if (blockers.length === 1) {
|
|
566
|
-
window.addEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
return function () {
|
|
570
|
-
unblock(); // Remove the beforeunload listener so the document may
|
|
571
|
-
// still be salvageable in the pagehide event.
|
|
572
|
-
// See https://html.spec.whatwg.org/#unloading-documents
|
|
573
|
-
|
|
574
|
-
if (!blockers.length) {
|
|
575
|
-
window.removeEventListener(BeforeUnloadEventType, promptBeforeUnload);
|
|
576
|
-
}
|
|
577
|
-
};
|
|
578
|
-
}
|
|
579
|
-
};
|
|
580
|
-
return history;
|
|
581
|
-
}
|
|
582
|
-
/**
|
|
583
|
-
* Memory history stores the current location in memory. It is designed for use
|
|
584
|
-
* in stateful non-browser environments like tests and React Native.
|
|
585
|
-
*
|
|
586
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#creatememoryhistory
|
|
587
|
-
*/
|
|
588
|
-
|
|
589
|
-
function createMemoryHistory(options) {
|
|
590
|
-
if (options === void 0) {
|
|
591
|
-
options = {};
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
var _options3 = options,
|
|
595
|
-
_options3$initialEntr = _options3.initialEntries,
|
|
596
|
-
initialEntries = _options3$initialEntr === void 0 ? ['/'] : _options3$initialEntr,
|
|
597
|
-
initialIndex = _options3.initialIndex;
|
|
598
|
-
var entries = initialEntries.map(function (entry) {
|
|
599
|
-
var location = readOnly(_extends$1({
|
|
600
|
-
pathname: '/',
|
|
601
|
-
search: '',
|
|
602
|
-
hash: '',
|
|
603
|
-
state: null,
|
|
604
|
-
key: createKey()
|
|
605
|
-
}, typeof entry === 'string' ? parsePath(entry) : entry));
|
|
606
|
-
process.env.NODE_ENV !== "production" ? warning$1(location.pathname.charAt(0) === '/', "Relative pathnames are not supported in createMemoryHistory({ initialEntries }) (invalid entry: " + JSON.stringify(entry) + ")") : void 0;
|
|
607
|
-
return location;
|
|
608
|
-
});
|
|
609
|
-
var index = clamp(initialIndex == null ? entries.length - 1 : initialIndex, 0, entries.length - 1);
|
|
610
|
-
var action = Action.Pop;
|
|
611
|
-
var location = entries[index];
|
|
612
|
-
var listeners = createEvents();
|
|
613
|
-
var blockers = createEvents();
|
|
614
|
-
|
|
615
|
-
function createHref(to) {
|
|
616
|
-
return typeof to === 'string' ? to : createPath(to);
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
function getNextLocation(to, state) {
|
|
620
|
-
if (state === void 0) {
|
|
621
|
-
state = null;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
return readOnly(_extends$1({
|
|
625
|
-
pathname: location.pathname,
|
|
626
|
-
search: '',
|
|
627
|
-
hash: ''
|
|
628
|
-
}, typeof to === 'string' ? parsePath(to) : to, {
|
|
629
|
-
state: state,
|
|
630
|
-
key: createKey()
|
|
631
|
-
}));
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
function allowTx(action, location, retry) {
|
|
635
|
-
return !blockers.length || (blockers.call({
|
|
636
|
-
action: action,
|
|
637
|
-
location: location,
|
|
638
|
-
retry: retry
|
|
639
|
-
}), false);
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
function applyTx(nextAction, nextLocation) {
|
|
643
|
-
action = nextAction;
|
|
644
|
-
location = nextLocation;
|
|
645
|
-
listeners.call({
|
|
646
|
-
action: action,
|
|
647
|
-
location: location
|
|
648
|
-
});
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
function push(to, state) {
|
|
652
|
-
var nextAction = Action.Push;
|
|
653
|
-
var nextLocation = getNextLocation(to, state);
|
|
654
|
-
|
|
655
|
-
function retry() {
|
|
656
|
-
push(to, state);
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
process.env.NODE_ENV !== "production" ? warning$1(location.pathname.charAt(0) === '/', "Relative pathnames are not supported in memory history.push(" + JSON.stringify(to) + ")") : void 0;
|
|
660
|
-
|
|
661
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
662
|
-
index += 1;
|
|
663
|
-
entries.splice(index, entries.length, nextLocation);
|
|
664
|
-
applyTx(nextAction, nextLocation);
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
function replace(to, state) {
|
|
669
|
-
var nextAction = Action.Replace;
|
|
670
|
-
var nextLocation = getNextLocation(to, state);
|
|
671
|
-
|
|
672
|
-
function retry() {
|
|
673
|
-
replace(to, state);
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
process.env.NODE_ENV !== "production" ? warning$1(location.pathname.charAt(0) === '/', "Relative pathnames are not supported in memory history.replace(" + JSON.stringify(to) + ")") : void 0;
|
|
677
|
-
|
|
678
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
679
|
-
entries[index] = nextLocation;
|
|
680
|
-
applyTx(nextAction, nextLocation);
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
function go(delta) {
|
|
685
|
-
var nextIndex = clamp(index + delta, 0, entries.length - 1);
|
|
686
|
-
var nextAction = Action.Pop;
|
|
687
|
-
var nextLocation = entries[nextIndex];
|
|
688
|
-
|
|
689
|
-
function retry() {
|
|
690
|
-
go(delta);
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
if (allowTx(nextAction, nextLocation, retry)) {
|
|
694
|
-
index = nextIndex;
|
|
695
|
-
applyTx(nextAction, nextLocation);
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
var history = {
|
|
700
|
-
get index() {
|
|
701
|
-
return index;
|
|
702
|
-
},
|
|
703
|
-
|
|
704
|
-
get action() {
|
|
705
|
-
return action;
|
|
706
|
-
},
|
|
707
|
-
|
|
708
|
-
get location() {
|
|
709
|
-
return location;
|
|
710
|
-
},
|
|
711
|
-
|
|
712
|
-
createHref: createHref,
|
|
713
|
-
push: push,
|
|
714
|
-
replace: replace,
|
|
715
|
-
go: go,
|
|
716
|
-
back: function back() {
|
|
717
|
-
go(-1);
|
|
718
|
-
},
|
|
719
|
-
forward: function forward() {
|
|
720
|
-
go(1);
|
|
721
|
-
},
|
|
722
|
-
listen: function listen(listener) {
|
|
723
|
-
return listeners.push(listener);
|
|
724
|
-
},
|
|
725
|
-
block: function block(blocker) {
|
|
726
|
-
return blockers.push(blocker);
|
|
727
|
-
}
|
|
728
|
-
};
|
|
729
|
-
return history;
|
|
730
|
-
} ////////////////////////////////////////////////////////////////////////////////
|
|
731
|
-
// UTILS
|
|
732
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
733
|
-
|
|
734
|
-
function clamp(n, lowerBound, upperBound) {
|
|
735
|
-
return Math.min(Math.max(n, lowerBound), upperBound);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
function promptBeforeUnload(event) {
|
|
739
|
-
// Cancel the event.
|
|
740
|
-
event.preventDefault(); // Chrome (and legacy IE) requires returnValue to be set.
|
|
741
|
-
|
|
742
|
-
event.returnValue = '';
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
function createEvents() {
|
|
746
|
-
var handlers = [];
|
|
747
|
-
return {
|
|
748
|
-
get length() {
|
|
749
|
-
return handlers.length;
|
|
750
|
-
},
|
|
751
|
-
|
|
752
|
-
push: function push(fn) {
|
|
753
|
-
handlers.push(fn);
|
|
754
|
-
return function () {
|
|
755
|
-
handlers = handlers.filter(function (handler) {
|
|
756
|
-
return handler !== fn;
|
|
757
|
-
});
|
|
758
|
-
};
|
|
759
|
-
},
|
|
760
|
-
call: function call(arg) {
|
|
761
|
-
handlers.forEach(function (fn) {
|
|
762
|
-
return fn && fn(arg);
|
|
763
|
-
});
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
function createKey() {
|
|
769
|
-
return Math.random().toString(36).substr(2, 8);
|
|
770
|
-
}
|
|
771
|
-
/**
|
|
772
|
-
* Creates a string URL path from the given pathname, search, and hash components.
|
|
773
|
-
*
|
|
774
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createpath
|
|
775
|
-
*/
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
function createPath(_ref) {
|
|
779
|
-
var _ref$pathname = _ref.pathname,
|
|
780
|
-
pathname = _ref$pathname === void 0 ? '/' : _ref$pathname,
|
|
781
|
-
_ref$search = _ref.search,
|
|
782
|
-
search = _ref$search === void 0 ? '' : _ref$search,
|
|
783
|
-
_ref$hash = _ref.hash,
|
|
784
|
-
hash = _ref$hash === void 0 ? '' : _ref$hash;
|
|
785
|
-
if (search && search !== '?') pathname += search.charAt(0) === '?' ? search : '?' + search;
|
|
786
|
-
if (hash && hash !== '#') pathname += hash.charAt(0) === '#' ? hash : '#' + hash;
|
|
787
|
-
return pathname;
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Parses a string URL path into its separate pathname, search, and hash components.
|
|
791
|
-
*
|
|
792
|
-
* @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#parsepath
|
|
793
|
-
*/
|
|
794
|
-
|
|
795
|
-
function parsePath(path) {
|
|
796
|
-
var parsedPath = {};
|
|
797
|
-
|
|
798
|
-
if (path) {
|
|
799
|
-
var hashIndex = path.indexOf('#');
|
|
800
|
-
|
|
801
|
-
if (hashIndex >= 0) {
|
|
802
|
-
parsedPath.hash = path.substr(hashIndex);
|
|
803
|
-
path = path.substr(0, hashIndex);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
var searchIndex = path.indexOf('?');
|
|
807
|
-
|
|
808
|
-
if (searchIndex >= 0) {
|
|
809
|
-
parsedPath.search = path.substr(searchIndex);
|
|
810
|
-
path = path.substr(0, searchIndex);
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
if (path) {
|
|
814
|
-
parsedPath.pathname = path;
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
return parsedPath;
|
|
819
|
-
}
|
|
820
|
-
|
|
821
|
-
var isProduction = process.env.NODE_ENV === 'production';
|
|
822
|
-
var prefix = 'Invariant failed';
|
|
823
|
-
function invariant(condition, message) {
|
|
824
|
-
if (condition) {
|
|
825
|
-
return;
|
|
826
|
-
}
|
|
827
|
-
if (isProduction) {
|
|
828
|
-
throw new Error(prefix);
|
|
829
|
-
}
|
|
830
|
-
var provided = typeof message === 'function' ? message() : message;
|
|
831
|
-
var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
|
|
832
|
-
throw new Error(value);
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
// type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
836
|
-
// k: infer I,
|
|
837
|
-
// ) => any
|
|
838
|
-
// ? I
|
|
839
|
-
// : never
|
|
840
|
-
|
|
841
|
-
/**
|
|
842
|
-
* This function returns `a` if `b` is deeply equal.
|
|
843
|
-
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
844
|
-
* This can be used for structural sharing between JSON values for example.
|
|
845
|
-
*/
|
|
846
|
-
function replaceEqualDeep(prev, next) {
|
|
847
|
-
if (prev === next) {
|
|
848
|
-
return prev;
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
const array = Array.isArray(prev) && Array.isArray(next);
|
|
852
|
-
|
|
853
|
-
if (array || isPlainObject(prev) && isPlainObject(next)) {
|
|
854
|
-
const aSize = array ? prev.length : Object.keys(prev).length;
|
|
855
|
-
const bItems = array ? next : Object.keys(next);
|
|
856
|
-
const bSize = bItems.length;
|
|
857
|
-
const copy = array ? [] : {};
|
|
858
|
-
let equalItems = 0;
|
|
859
|
-
|
|
860
|
-
for (let i = 0; i < bSize; i++) {
|
|
861
|
-
const key = array ? i : bItems[i];
|
|
862
|
-
copy[key] = replaceEqualDeep(prev[key], next[key]);
|
|
863
|
-
|
|
864
|
-
if (copy[key] === prev[key]) {
|
|
865
|
-
equalItems++;
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
return aSize === bSize && equalItems === aSize ? prev : copy;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
return next;
|
|
873
|
-
} // Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
874
|
-
|
|
875
|
-
function isPlainObject(o) {
|
|
876
|
-
if (!hasObjectPrototype(o)) {
|
|
877
|
-
return false;
|
|
878
|
-
} // If has modified constructor
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
const ctor = o.constructor;
|
|
882
|
-
|
|
883
|
-
if (typeof ctor === 'undefined') {
|
|
884
|
-
return true;
|
|
885
|
-
} // If has modified prototype
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
const prot = ctor.prototype;
|
|
889
|
-
|
|
890
|
-
if (!hasObjectPrototype(prot)) {
|
|
891
|
-
return false;
|
|
892
|
-
} // If constructor does not have an Object-specific method
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
|
896
|
-
return false;
|
|
897
|
-
} // Most likely a plain Object
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
return true;
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
function hasObjectPrototype(o) {
|
|
904
|
-
return Object.prototype.toString.call(o) === '[object Object]';
|
|
905
|
-
}
|
|
11
|
+
import { createMemoryHistory, createBrowserHistory } from 'history';
|
|
12
|
+
export { createBrowserHistory, createHashHistory, createMemoryHistory } from 'history';
|
|
13
|
+
import invariant from 'tiny-invariant';
|
|
14
|
+
export { default as invariant } from 'tiny-invariant';
|
|
15
|
+
import { createStore, batch } from '@solidjs/reactivity';
|
|
906
16
|
|
|
907
17
|
function last(arr) {
|
|
908
18
|
return arr[arr.length - 1];
|
|
@@ -910,26 +20,27 @@ function last(arr) {
|
|
|
910
20
|
function warning(cond, message) {
|
|
911
21
|
if (cond) {
|
|
912
22
|
if (typeof console !== 'undefined') console.warn(message);
|
|
913
|
-
|
|
914
23
|
try {
|
|
915
24
|
throw new Error(message);
|
|
916
|
-
} catch
|
|
25
|
+
} catch {}
|
|
917
26
|
}
|
|
918
|
-
|
|
919
27
|
return true;
|
|
920
28
|
}
|
|
921
|
-
|
|
922
29
|
function isFunction(d) {
|
|
923
30
|
return typeof d === 'function';
|
|
924
31
|
}
|
|
925
|
-
|
|
926
32
|
function functionalUpdate(updater, previous) {
|
|
927
33
|
if (isFunction(updater)) {
|
|
928
34
|
return updater(previous);
|
|
929
35
|
}
|
|
930
|
-
|
|
931
36
|
return updater;
|
|
932
37
|
}
|
|
38
|
+
function pick(parent, keys) {
|
|
39
|
+
return keys.reduce((obj, key) => {
|
|
40
|
+
obj[key] = parent[key];
|
|
41
|
+
return obj;
|
|
42
|
+
}, {});
|
|
43
|
+
}
|
|
933
44
|
|
|
934
45
|
function joinPaths(paths) {
|
|
935
46
|
return cleanPath(paths.filter(Boolean).join('/'));
|
|
@@ -948,8 +59,8 @@ function trimPath(path) {
|
|
|
948
59
|
return trimPathRight(trimPathLeft(path));
|
|
949
60
|
}
|
|
950
61
|
function resolvePath(basepath, base, to) {
|
|
951
|
-
base = base.replace(new RegExp(
|
|
952
|
-
to = to.replace(new RegExp(
|
|
62
|
+
base = base.replace(new RegExp(`^${basepath}`), '/');
|
|
63
|
+
to = to.replace(new RegExp(`^${basepath}`), '/');
|
|
953
64
|
let baseSegments = parsePathname(base);
|
|
954
65
|
const toSegments = parsePathname(to);
|
|
955
66
|
toSegments.forEach((toSegment, index) => {
|
|
@@ -963,12 +74,10 @@ function resolvePath(basepath, base, to) {
|
|
|
963
74
|
} else ;
|
|
964
75
|
} else if (toSegment.value === '..') {
|
|
965
76
|
var _last;
|
|
966
|
-
|
|
967
77
|
// Extra trailing slash? pop it off
|
|
968
78
|
if (baseSegments.length > 1 && ((_last = last(baseSegments)) == null ? void 0 : _last.value) === '/') {
|
|
969
79
|
baseSegments.pop();
|
|
970
80
|
}
|
|
971
|
-
|
|
972
81
|
baseSegments.pop();
|
|
973
82
|
} else if (toSegment.value === '.') {
|
|
974
83
|
return;
|
|
@@ -983,10 +92,8 @@ function parsePathname(pathname) {
|
|
|
983
92
|
if (!pathname) {
|
|
984
93
|
return [];
|
|
985
94
|
}
|
|
986
|
-
|
|
987
95
|
pathname = cleanPath(pathname);
|
|
988
96
|
const segments = [];
|
|
989
|
-
|
|
990
97
|
if (pathname.slice(0, 1) === '/') {
|
|
991
98
|
pathname = pathname.substring(1);
|
|
992
99
|
segments.push({
|
|
@@ -994,12 +101,11 @@ function parsePathname(pathname) {
|
|
|
994
101
|
value: '/'
|
|
995
102
|
});
|
|
996
103
|
}
|
|
997
|
-
|
|
998
104
|
if (!pathname) {
|
|
999
105
|
return segments;
|
|
1000
|
-
}
|
|
1001
|
-
|
|
106
|
+
}
|
|
1002
107
|
|
|
108
|
+
// Remove empty segments and '.' segments
|
|
1003
109
|
const split = pathname.split('/').filter(Boolean);
|
|
1004
110
|
segments.push(...split.map(part => {
|
|
1005
111
|
if (part.startsWith('*')) {
|
|
@@ -1008,20 +114,17 @@ function parsePathname(pathname) {
|
|
|
1008
114
|
value: part
|
|
1009
115
|
};
|
|
1010
116
|
}
|
|
1011
|
-
|
|
1012
|
-
if (part.charAt(0) === ':') {
|
|
117
|
+
if (part.charAt(0) === '$') {
|
|
1013
118
|
return {
|
|
1014
119
|
type: 'param',
|
|
1015
120
|
value: part
|
|
1016
121
|
};
|
|
1017
122
|
}
|
|
1018
|
-
|
|
1019
123
|
return {
|
|
1020
124
|
type: 'pathname',
|
|
1021
125
|
value: part
|
|
1022
126
|
};
|
|
1023
127
|
}));
|
|
1024
|
-
|
|
1025
128
|
if (pathname.slice(-1) === '/') {
|
|
1026
129
|
pathname = pathname.substring(1);
|
|
1027
130
|
segments.push({
|
|
@@ -1029,7 +132,6 @@ function parsePathname(pathname) {
|
|
|
1029
132
|
value: '/'
|
|
1030
133
|
});
|
|
1031
134
|
}
|
|
1032
|
-
|
|
1033
135
|
return segments;
|
|
1034
136
|
}
|
|
1035
137
|
function interpolatePath(path, params, leaveWildcard) {
|
|
@@ -1038,57 +140,48 @@ function interpolatePath(path, params, leaveWildcard) {
|
|
|
1038
140
|
if (segment.value === '*' && !leaveWildcard) {
|
|
1039
141
|
return '';
|
|
1040
142
|
}
|
|
1041
|
-
|
|
1042
143
|
if (segment.type === 'param') {
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
return (_segment$value$substr = params[segment.value.substring(1)]) != null ? _segment$value$substr : '';
|
|
144
|
+
return params[segment.value.substring(1)] ?? '';
|
|
1046
145
|
}
|
|
1047
|
-
|
|
1048
146
|
return segment.value;
|
|
1049
147
|
}));
|
|
1050
148
|
}
|
|
1051
|
-
function matchPathname(currentPathname, matchLocation) {
|
|
1052
|
-
const pathParams = matchByPath(currentPathname, matchLocation);
|
|
149
|
+
function matchPathname(basepath, currentPathname, matchLocation) {
|
|
150
|
+
const pathParams = matchByPath(basepath, currentPathname, matchLocation);
|
|
151
|
+
// const searchMatched = matchBySearch(currentLocation.search, matchLocation)
|
|
1053
152
|
|
|
1054
153
|
if (matchLocation.to && !pathParams) {
|
|
1055
154
|
return;
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
// }
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
return pathParams != null ? pathParams : {};
|
|
155
|
+
}
|
|
156
|
+
return pathParams ?? {};
|
|
1062
157
|
}
|
|
1063
|
-
function matchByPath(from, matchLocation) {
|
|
1064
|
-
|
|
1065
|
-
|
|
158
|
+
function matchByPath(basepath, from, matchLocation) {
|
|
159
|
+
if (!from.startsWith(basepath)) {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
from = basepath != '/' ? from.substring(basepath.length) : from;
|
|
1066
163
|
const baseSegments = parsePathname(from);
|
|
1067
|
-
const
|
|
164
|
+
const to = `${matchLocation.to ?? '*'}`;
|
|
165
|
+
const routeSegments = parsePathname(to);
|
|
1068
166
|
const params = {};
|
|
1069
|
-
|
|
1070
167
|
let isMatch = (() => {
|
|
1071
168
|
for (let i = 0; i < Math.max(baseSegments.length, routeSegments.length); i++) {
|
|
1072
169
|
const baseSegment = baseSegments[i];
|
|
1073
170
|
const routeSegment = routeSegments[i];
|
|
1074
171
|
const isLastRouteSegment = i === routeSegments.length - 1;
|
|
1075
172
|
const isLastBaseSegment = i === baseSegments.length - 1;
|
|
1076
|
-
|
|
1077
173
|
if (routeSegment) {
|
|
1078
174
|
if (routeSegment.type === 'wildcard') {
|
|
1079
175
|
if (baseSegment != null && baseSegment.value) {
|
|
1080
176
|
params['*'] = joinPaths(baseSegments.slice(i).map(d => d.value));
|
|
1081
177
|
return true;
|
|
1082
178
|
}
|
|
1083
|
-
|
|
1084
179
|
return false;
|
|
1085
180
|
}
|
|
1086
|
-
|
|
1087
181
|
if (routeSegment.type === 'pathname') {
|
|
1088
182
|
if (routeSegment.value === '/' && !(baseSegment != null && baseSegment.value)) {
|
|
1089
183
|
return true;
|
|
1090
184
|
}
|
|
1091
|
-
|
|
1092
185
|
if (baseSegment) {
|
|
1093
186
|
if (matchLocation.caseSensitive) {
|
|
1094
187
|
if (routeSegment.value !== baseSegment.value) {
|
|
@@ -1099,41 +192,36 @@ function matchByPath(from, matchLocation) {
|
|
|
1099
192
|
}
|
|
1100
193
|
}
|
|
1101
194
|
}
|
|
1102
|
-
|
|
1103
195
|
if (!baseSegment) {
|
|
1104
196
|
return false;
|
|
1105
197
|
}
|
|
1106
|
-
|
|
1107
198
|
if (routeSegment.type === 'param') {
|
|
1108
199
|
if ((baseSegment == null ? void 0 : baseSegment.value) === '/') {
|
|
1109
200
|
return false;
|
|
1110
201
|
}
|
|
1111
|
-
|
|
1112
|
-
if (!baseSegment.value.startsWith(':')) {
|
|
202
|
+
if (baseSegment.value.charAt(0) !== '$') {
|
|
1113
203
|
params[routeSegment.value.substring(1)] = baseSegment.value;
|
|
1114
204
|
}
|
|
1115
205
|
}
|
|
1116
206
|
}
|
|
1117
|
-
|
|
1118
207
|
if (isLastRouteSegment && !isLastBaseSegment) {
|
|
1119
208
|
return !!matchLocation.fuzzy;
|
|
1120
209
|
}
|
|
1121
210
|
}
|
|
1122
|
-
|
|
1123
211
|
return true;
|
|
1124
212
|
})();
|
|
1125
|
-
|
|
1126
213
|
return isMatch ? params : undefined;
|
|
1127
214
|
}
|
|
1128
215
|
|
|
1129
216
|
// @ts-nocheck
|
|
217
|
+
|
|
1130
218
|
// 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.
|
|
219
|
+
|
|
1131
220
|
function encode(obj, pfx) {
|
|
1132
221
|
var k,
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
222
|
+
i,
|
|
223
|
+
tmp,
|
|
224
|
+
str = '';
|
|
1137
225
|
for (k in obj) {
|
|
1138
226
|
if ((tmp = obj[k]) !== void 0) {
|
|
1139
227
|
if (Array.isArray(tmp)) {
|
|
@@ -1147,10 +235,8 @@ function encode(obj, pfx) {
|
|
|
1147
235
|
}
|
|
1148
236
|
}
|
|
1149
237
|
}
|
|
1150
|
-
|
|
1151
238
|
return (pfx || '') + str;
|
|
1152
239
|
}
|
|
1153
|
-
|
|
1154
240
|
function toValue(mix) {
|
|
1155
241
|
if (!mix) return '';
|
|
1156
242
|
var str = decodeURIComponent(mix);
|
|
@@ -1159,221 +245,190 @@ function toValue(mix) {
|
|
|
1159
245
|
if (str.charAt(0) === '0') return str;
|
|
1160
246
|
return +str * 0 === 0 ? +str : str;
|
|
1161
247
|
}
|
|
1162
|
-
|
|
1163
248
|
function decode(str) {
|
|
1164
249
|
var tmp,
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
250
|
+
k,
|
|
251
|
+
out = {},
|
|
252
|
+
arr = str.split('&');
|
|
1169
253
|
while (tmp = arr.shift()) {
|
|
1170
254
|
tmp = tmp.split('=');
|
|
1171
255
|
k = tmp.shift();
|
|
1172
|
-
|
|
1173
256
|
if (out[k] !== void 0) {
|
|
1174
257
|
out[k] = [].concat(out[k], toValue(tmp.shift()));
|
|
1175
258
|
} else {
|
|
1176
259
|
out[k] = toValue(tmp.shift());
|
|
1177
260
|
}
|
|
1178
261
|
}
|
|
1179
|
-
|
|
1180
262
|
return out;
|
|
1181
263
|
}
|
|
1182
264
|
|
|
1183
|
-
function
|
|
1184
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
1185
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
1186
|
-
var source = arguments[i];
|
|
1187
|
-
|
|
1188
|
-
for (var key in source) {
|
|
1189
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1190
|
-
target[key] = source[key];
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
|
|
1195
|
-
return target;
|
|
1196
|
-
};
|
|
1197
|
-
return _extends.apply(this, arguments);
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
function createRoute(routeConfig, options, parent, router) {
|
|
265
|
+
function createRoute(routeConfig, options, originalIndex, parent, router) {
|
|
1201
266
|
const {
|
|
1202
267
|
id,
|
|
1203
268
|
routeId,
|
|
1204
269
|
path: routePath,
|
|
1205
270
|
fullPath
|
|
1206
271
|
} = routeConfig;
|
|
1207
|
-
|
|
1208
|
-
const action = router.state.actions[id] || (() => {
|
|
1209
|
-
router.state.actions[id] = {
|
|
1210
|
-
pending: [],
|
|
1211
|
-
submit: async (submission, actionOpts) => {
|
|
1212
|
-
var _actionOpts$invalidat;
|
|
1213
|
-
|
|
1214
|
-
if (!route) {
|
|
1215
|
-
return;
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
|
|
1219
|
-
const actionState = {
|
|
1220
|
-
submittedAt: Date.now(),
|
|
1221
|
-
status: 'pending',
|
|
1222
|
-
submission
|
|
1223
|
-
};
|
|
1224
|
-
action.current = actionState;
|
|
1225
|
-
action.latest = actionState;
|
|
1226
|
-
action.pending.push(actionState);
|
|
1227
|
-
router.state = _extends({}, router.state, {
|
|
1228
|
-
currentAction: actionState,
|
|
1229
|
-
latestAction: actionState
|
|
1230
|
-
});
|
|
1231
|
-
router.notify();
|
|
1232
|
-
|
|
1233
|
-
try {
|
|
1234
|
-
const res = await (route.options.action == null ? void 0 : route.options.action(submission));
|
|
1235
|
-
actionState.data = res;
|
|
1236
|
-
|
|
1237
|
-
if (invalidate) {
|
|
1238
|
-
router.invalidateRoute({
|
|
1239
|
-
to: '.',
|
|
1240
|
-
fromCurrent: true
|
|
1241
|
-
});
|
|
1242
|
-
await router.reload();
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
actionState.status = 'success';
|
|
1246
|
-
return res;
|
|
1247
|
-
} catch (err) {
|
|
1248
|
-
console.error(err);
|
|
1249
|
-
actionState.error = err;
|
|
1250
|
-
actionState.status = 'error';
|
|
1251
|
-
} finally {
|
|
1252
|
-
action.pending = action.pending.filter(d => d !== actionState);
|
|
1253
|
-
router.removeActionQueue.push({
|
|
1254
|
-
action,
|
|
1255
|
-
actionState
|
|
1256
|
-
});
|
|
1257
|
-
router.notify();
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
};
|
|
1261
|
-
return router.state.actions[id];
|
|
1262
|
-
})();
|
|
1263
|
-
|
|
1264
|
-
const loader = router.state.loaders[id] || (() => {
|
|
1265
|
-
router.state.loaders[id] = {
|
|
1266
|
-
pending: [],
|
|
1267
|
-
fetch: async loaderContext => {
|
|
1268
|
-
if (!route) {
|
|
1269
|
-
return;
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
const loaderState = {
|
|
1273
|
-
loadedAt: Date.now(),
|
|
1274
|
-
loaderContext
|
|
1275
|
-
};
|
|
1276
|
-
loader.current = loaderState;
|
|
1277
|
-
loader.latest = loaderState;
|
|
1278
|
-
loader.pending.push(loaderState); // router.state = {
|
|
1279
|
-
// ...router.state,
|
|
1280
|
-
// currentAction: loaderState,
|
|
1281
|
-
// latestAction: loaderState,
|
|
1282
|
-
// }
|
|
1283
|
-
|
|
1284
|
-
router.notify();
|
|
1285
|
-
|
|
1286
|
-
try {
|
|
1287
|
-
return await (route.options.loader == null ? void 0 : route.options.loader(loaderContext));
|
|
1288
|
-
} finally {
|
|
1289
|
-
loader.pending = loader.pending.filter(d => d !== loaderState); // router.removeActionQueue.push({ loader, loaderState })
|
|
1290
|
-
|
|
1291
|
-
router.notify();
|
|
1292
|
-
}
|
|
1293
|
-
}
|
|
1294
|
-
};
|
|
1295
|
-
return router.state.loaders[id];
|
|
1296
|
-
})();
|
|
1297
|
-
|
|
1298
272
|
let route = {
|
|
273
|
+
routeInfo: undefined,
|
|
1299
274
|
routeId: id,
|
|
1300
275
|
routeRouteId: routeId,
|
|
276
|
+
originalIndex,
|
|
1301
277
|
routePath,
|
|
1302
278
|
fullPath,
|
|
1303
279
|
options,
|
|
1304
280
|
router,
|
|
1305
281
|
childRoutes: undefined,
|
|
1306
282
|
parentRoute: parent,
|
|
1307
|
-
action
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
283
|
+
get action() {
|
|
284
|
+
let action = router.store.actions[id] || (() => {
|
|
285
|
+
router.setStore(s => {
|
|
286
|
+
s.actions[id] = {
|
|
287
|
+
submissions: [],
|
|
288
|
+
submit: async (submission, actionOpts) => {
|
|
289
|
+
if (!route) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
const invalidate = (actionOpts == null ? void 0 : actionOpts.invalidate) ?? true;
|
|
293
|
+
const [actionStore, setActionStore] = createStore({
|
|
294
|
+
submittedAt: Date.now(),
|
|
295
|
+
status: 'pending',
|
|
296
|
+
submission,
|
|
297
|
+
isMulti: !!(actionOpts != null && actionOpts.multi)
|
|
298
|
+
});
|
|
299
|
+
router.setStore(s => {
|
|
300
|
+
if (!(actionOpts != null && actionOpts.multi)) {
|
|
301
|
+
s.actions[id].submissions = action.submissions.filter(d => d.isMulti);
|
|
302
|
+
}
|
|
303
|
+
s.actions[id].current = actionStore;
|
|
304
|
+
s.actions[id].latest = actionStore;
|
|
305
|
+
s.actions[id].submissions.push(actionStore);
|
|
306
|
+
});
|
|
307
|
+
try {
|
|
308
|
+
const res = await (route.options.action == null ? void 0 : route.options.action(submission));
|
|
309
|
+
setActionStore(s => {
|
|
310
|
+
s.data = res;
|
|
311
|
+
});
|
|
312
|
+
if (invalidate) {
|
|
313
|
+
router.invalidateRoute({
|
|
314
|
+
to: '.',
|
|
315
|
+
fromCurrent: true
|
|
316
|
+
});
|
|
317
|
+
await router.reload();
|
|
318
|
+
}
|
|
319
|
+
setActionStore(s => {
|
|
320
|
+
s.status = 'success';
|
|
321
|
+
});
|
|
322
|
+
return res;
|
|
323
|
+
} catch (err) {
|
|
324
|
+
console.error(err);
|
|
325
|
+
setActionStore(s => {
|
|
326
|
+
s.error = err;
|
|
327
|
+
s.status = 'error';
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
});
|
|
333
|
+
return router.store.actions[id];
|
|
334
|
+
})();
|
|
335
|
+
return action;
|
|
1318
336
|
},
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
337
|
+
get loader() {
|
|
338
|
+
let loader = router.store.loaders[id] || (() => {
|
|
339
|
+
router.setStore(s => {
|
|
340
|
+
s.loaders[id] = {
|
|
341
|
+
pending: [],
|
|
342
|
+
fetch: async loaderContext => {
|
|
343
|
+
if (!route) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const loaderState = {
|
|
347
|
+
loadedAt: Date.now(),
|
|
348
|
+
loaderContext
|
|
349
|
+
};
|
|
350
|
+
router.setStore(s => {
|
|
351
|
+
s.loaders[id].current = loaderState;
|
|
352
|
+
s.loaders[id].latest = loaderState;
|
|
353
|
+
s.loaders[id].pending.push(loaderState);
|
|
354
|
+
});
|
|
355
|
+
try {
|
|
356
|
+
return await (route.options.loader == null ? void 0 : route.options.loader(loaderContext));
|
|
357
|
+
} finally {
|
|
358
|
+
router.setStore(s => {
|
|
359
|
+
s.loaders[id].pending = s.loaders[id].pending.filter(d => d !== loaderState);
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
};
|
|
364
|
+
});
|
|
365
|
+
return router.store.loaders[id];
|
|
366
|
+
})();
|
|
367
|
+
return loader;
|
|
1323
368
|
}
|
|
369
|
+
|
|
370
|
+
// buildLink: (options) => {
|
|
371
|
+
// return router.buildLink({
|
|
372
|
+
// ...options,
|
|
373
|
+
// from: fullPath,
|
|
374
|
+
// } as any) as any
|
|
375
|
+
// },
|
|
376
|
+
|
|
377
|
+
// navigate: (options) => {
|
|
378
|
+
// return router.navigate({
|
|
379
|
+
// ...options,
|
|
380
|
+
// from: fullPath,
|
|
381
|
+
// } as any) as any
|
|
382
|
+
// },
|
|
383
|
+
|
|
384
|
+
// matchRoute: (matchLocation, opts) => {
|
|
385
|
+
// return router.matchRoute(
|
|
386
|
+
// {
|
|
387
|
+
// ...matchLocation,
|
|
388
|
+
// from: fullPath,
|
|
389
|
+
// } as any,
|
|
390
|
+
// opts,
|
|
391
|
+
// ) as any
|
|
392
|
+
// },
|
|
1324
393
|
};
|
|
394
|
+
|
|
1325
395
|
router.options.createRoute == null ? void 0 : router.options.createRoute({
|
|
1326
396
|
router,
|
|
1327
397
|
route
|
|
1328
398
|
});
|
|
1329
399
|
return route;
|
|
1330
400
|
}
|
|
1331
|
-
function cascadeLoaderData(matches) {
|
|
1332
|
-
matches.forEach((match, index) => {
|
|
1333
|
-
const parent = matches[index - 1];
|
|
1334
|
-
|
|
1335
|
-
if (parent) {
|
|
1336
|
-
match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
|
|
1337
|
-
}
|
|
1338
|
-
});
|
|
1339
|
-
}
|
|
1340
401
|
|
|
1341
402
|
const rootRouteId = '__root__';
|
|
1342
|
-
const createRouteConfig = function
|
|
403
|
+
const createRouteConfig = function (options, children, isRoot, parentId, parentPath) {
|
|
1343
404
|
if (options === void 0) {
|
|
1344
405
|
options = {};
|
|
1345
406
|
}
|
|
1346
|
-
|
|
1347
407
|
if (isRoot === void 0) {
|
|
1348
408
|
isRoot = true;
|
|
1349
409
|
}
|
|
1350
|
-
|
|
1351
410
|
if (isRoot) {
|
|
1352
411
|
options.path = rootRouteId;
|
|
1353
|
-
}
|
|
1354
|
-
|
|
412
|
+
}
|
|
1355
413
|
|
|
414
|
+
// Strip the root from parentIds
|
|
1356
415
|
if (parentId === rootRouteId) {
|
|
1357
416
|
parentId = '';
|
|
1358
417
|
}
|
|
418
|
+
let path = isRoot ? rootRouteId : options.path;
|
|
1359
419
|
|
|
1360
|
-
|
|
1361
|
-
|
|
420
|
+
// If the path is anything other than an index path, trim it up
|
|
1362
421
|
if (path && path !== '/') {
|
|
1363
422
|
path = trimPath(path);
|
|
1364
423
|
}
|
|
1365
|
-
|
|
1366
424
|
const routeId = path || options.id;
|
|
1367
425
|
let id = joinPaths([parentId, routeId]);
|
|
1368
|
-
|
|
1369
426
|
if (path === rootRouteId) {
|
|
1370
427
|
path = '/';
|
|
1371
428
|
}
|
|
1372
|
-
|
|
1373
429
|
if (id !== rootRouteId) {
|
|
1374
430
|
id = joinPaths(['/', id]);
|
|
1375
431
|
}
|
|
1376
|
-
|
|
1377
432
|
const fullPath = id === rootRouteId ? '/' : trimPathRight(joinPaths([parentPath, path]));
|
|
1378
433
|
return {
|
|
1379
434
|
id: id,
|
|
@@ -1382,256 +437,340 @@ const createRouteConfig = function createRouteConfig(options, children, isRoot,
|
|
|
1382
437
|
fullPath: fullPath,
|
|
1383
438
|
options: options,
|
|
1384
439
|
children,
|
|
1385
|
-
createChildren: cb => createRouteConfig(options, cb(childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)), false, parentId, parentPath),
|
|
1386
440
|
addChildren: children => createRouteConfig(options, children, false, parentId, parentPath),
|
|
1387
|
-
createRoute: childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath)
|
|
441
|
+
createRoute: childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath),
|
|
442
|
+
generate: () => {
|
|
443
|
+
invariant(false, `routeConfig.generate() is used by TanStack Router's file-based routing code generation and should not actually be called during runtime. `);
|
|
444
|
+
}
|
|
1388
445
|
};
|
|
1389
446
|
};
|
|
1390
447
|
|
|
1391
|
-
|
|
448
|
+
/**
|
|
449
|
+
* This function returns `a` if `b` is deeply equal.
|
|
450
|
+
* If not, it will replace any deeply equal children of `b` with those of `a`.
|
|
451
|
+
* This can be used for structural sharing between JSON values for example.
|
|
452
|
+
*/
|
|
453
|
+
function sharedClone(prev, next, touchAll) {
|
|
454
|
+
const things = new Map();
|
|
455
|
+
function recurse(prev, next) {
|
|
456
|
+
if (prev === next) {
|
|
457
|
+
return prev;
|
|
458
|
+
}
|
|
459
|
+
if (things.has(next)) {
|
|
460
|
+
return things.get(next);
|
|
461
|
+
}
|
|
462
|
+
const prevIsArray = Array.isArray(prev);
|
|
463
|
+
const nextIsArray = Array.isArray(next);
|
|
464
|
+
const prevIsObj = isPlainObject(prev);
|
|
465
|
+
const nextIsObj = isPlainObject(next);
|
|
466
|
+
const isArray = prevIsArray && nextIsArray;
|
|
467
|
+
const isObj = prevIsObj && nextIsObj;
|
|
468
|
+
const isSameStructure = isArray || isObj;
|
|
469
|
+
|
|
470
|
+
// Both are arrays or objects
|
|
471
|
+
if (isSameStructure) {
|
|
472
|
+
const aSize = isArray ? prev.length : Object.keys(prev).length;
|
|
473
|
+
const bItems = isArray ? next : Object.keys(next);
|
|
474
|
+
const bSize = bItems.length;
|
|
475
|
+
const copy = isArray ? [] : {};
|
|
476
|
+
let equalItems = 0;
|
|
477
|
+
for (let i = 0; i < bSize; i++) {
|
|
478
|
+
const key = isArray ? i : bItems[i];
|
|
479
|
+
if (copy[key] === prev[key]) {
|
|
480
|
+
equalItems++;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (aSize === bSize && equalItems === aSize) {
|
|
484
|
+
things.set(next, prev);
|
|
485
|
+
return prev;
|
|
486
|
+
}
|
|
487
|
+
things.set(next, copy);
|
|
488
|
+
for (let i = 0; i < bSize; i++) {
|
|
489
|
+
const key = isArray ? i : bItems[i];
|
|
490
|
+
if (typeof bItems[i] === 'function') {
|
|
491
|
+
copy[key] = prev[key];
|
|
492
|
+
} else {
|
|
493
|
+
copy[key] = recurse(prev[key], next[key]);
|
|
494
|
+
}
|
|
495
|
+
if (copy[key] === prev[key]) {
|
|
496
|
+
equalItems++;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return copy;
|
|
500
|
+
}
|
|
501
|
+
if (nextIsArray) {
|
|
502
|
+
const copy = [];
|
|
503
|
+
things.set(next, copy);
|
|
504
|
+
for (let i = 0; i < next.length; i++) {
|
|
505
|
+
copy[i] = recurse(undefined, next[i]);
|
|
506
|
+
}
|
|
507
|
+
return copy;
|
|
508
|
+
}
|
|
509
|
+
if (nextIsObj) {
|
|
510
|
+
const copy = {};
|
|
511
|
+
things.set(next, copy);
|
|
512
|
+
const nextKeys = Object.keys(next);
|
|
513
|
+
for (let i = 0; i < nextKeys.length; i++) {
|
|
514
|
+
const key = nextKeys[i];
|
|
515
|
+
copy[key] = recurse(undefined, next[key]);
|
|
516
|
+
}
|
|
517
|
+
return copy;
|
|
518
|
+
}
|
|
519
|
+
return next;
|
|
520
|
+
}
|
|
521
|
+
return recurse(prev, next);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Copied from: https://github.com/jonschlinkert/is-plain-object
|
|
525
|
+
function isPlainObject(o) {
|
|
526
|
+
if (!hasObjectPrototype(o)) {
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// If has modified constructor
|
|
531
|
+
const ctor = o.constructor;
|
|
532
|
+
if (typeof ctor === 'undefined') {
|
|
533
|
+
return true;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// If has modified prototype
|
|
537
|
+
const prot = ctor.prototype;
|
|
538
|
+
if (!hasObjectPrototype(prot)) {
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// If constructor does not have an Object-specific method
|
|
543
|
+
if (!prot.hasOwnProperty('isPrototypeOf')) {
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Most likely a plain Object
|
|
548
|
+
return true;
|
|
549
|
+
}
|
|
550
|
+
function hasObjectPrototype(o) {
|
|
551
|
+
return Object.prototype.toString.call(o) === '[object Object]';
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
1392
555
|
function createRouteMatch(router, route, opts) {
|
|
1393
|
-
|
|
1394
|
-
|
|
556
|
+
let componentsPromise;
|
|
557
|
+
let dataPromise;
|
|
558
|
+
let latestId = '';
|
|
559
|
+
let resolve = () => {};
|
|
560
|
+
function setLoaderData(loaderData) {
|
|
561
|
+
batch(() => {
|
|
562
|
+
setStore(s => {
|
|
563
|
+
s.routeLoaderData = sharedClone(s.routeLoaderData, loaderData);
|
|
564
|
+
});
|
|
565
|
+
updateLoaderData();
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
function updateLoaderData() {
|
|
569
|
+
setStore(s => {
|
|
570
|
+
var _store$parentMatch;
|
|
571
|
+
s.loaderData = sharedClone(s.loaderData, {
|
|
572
|
+
...((_store$parentMatch = store.parentMatch) == null ? void 0 : _store$parentMatch.store.loaderData),
|
|
573
|
+
...s.routeLoaderData
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
const [store, setStore] = createStore({
|
|
1395
578
|
routeSearch: {},
|
|
1396
579
|
search: {},
|
|
1397
|
-
childMatches: [],
|
|
1398
580
|
status: 'idle',
|
|
1399
581
|
routeLoaderData: {},
|
|
1400
582
|
loaderData: {},
|
|
1401
|
-
isPending: false,
|
|
1402
583
|
isFetching: false,
|
|
1403
|
-
|
|
584
|
+
invalid: false,
|
|
1404
585
|
invalidAt: Infinity,
|
|
1405
|
-
|
|
586
|
+
get isInvalid() {
|
|
1406
587
|
const now = Date.now();
|
|
1407
|
-
return
|
|
1408
|
-
}
|
|
588
|
+
return this.invalid || this.invalidAt < now;
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
const routeMatch = {
|
|
592
|
+
...route,
|
|
593
|
+
...opts,
|
|
594
|
+
store,
|
|
595
|
+
// setStore,
|
|
596
|
+
router,
|
|
597
|
+
childMatches: [],
|
|
1409
598
|
__: {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
},
|
|
1418
|
-
startPending: () => {
|
|
1419
|
-
var _routeMatch$options$p, _routeMatch$options$p2;
|
|
1420
|
-
|
|
1421
|
-
const pendingMs = (_routeMatch$options$p = routeMatch.options.pendingMs) != null ? _routeMatch$options$p : router.options.defaultPendingMs;
|
|
1422
|
-
const pendingMinMs = (_routeMatch$options$p2 = routeMatch.options.pendingMinMs) != null ? _routeMatch$options$p2 : router.options.defaultPendingMinMs;
|
|
1423
|
-
|
|
1424
|
-
if (routeMatch.__.pendingTimeout || routeMatch.status !== 'loading' || typeof pendingMs === 'undefined') {
|
|
1425
|
-
return;
|
|
1426
|
-
}
|
|
1427
|
-
|
|
1428
|
-
routeMatch.__.pendingTimeout = setTimeout(() => {
|
|
1429
|
-
routeMatch.isPending = true;
|
|
1430
|
-
|
|
1431
|
-
routeMatch.__.resolve();
|
|
1432
|
-
|
|
1433
|
-
if (typeof pendingMinMs !== 'undefined') {
|
|
1434
|
-
routeMatch.__.pendingMinPromise = new Promise(r => routeMatch.__.pendingMinTimeout = setTimeout(r, pendingMinMs));
|
|
1435
|
-
}
|
|
1436
|
-
}, pendingMs);
|
|
1437
|
-
},
|
|
1438
|
-
cancelPending: () => {
|
|
1439
|
-
routeMatch.isPending = false;
|
|
1440
|
-
clearTimeout(routeMatch.__.pendingTimeout);
|
|
1441
|
-
clearTimeout(routeMatch.__.pendingMinTimeout);
|
|
1442
|
-
delete routeMatch.__.pendingMinPromise;
|
|
599
|
+
setParentMatch: parentMatch => {
|
|
600
|
+
batch(() => {
|
|
601
|
+
setStore(s => {
|
|
602
|
+
s.parentMatch = parentMatch;
|
|
603
|
+
});
|
|
604
|
+
updateLoaderData();
|
|
605
|
+
});
|
|
1443
606
|
},
|
|
1444
|
-
|
|
1445
|
-
// routeMatch.parentMatch = parentMatch
|
|
1446
|
-
// },
|
|
1447
|
-
// addChildMatch: (childMatch: RouteMatch) => {
|
|
1448
|
-
// if (
|
|
1449
|
-
// routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
|
|
1450
|
-
// ) {
|
|
1451
|
-
// return
|
|
1452
|
-
// }
|
|
1453
|
-
// routeMatch.childMatches.push(childMatch)
|
|
1454
|
-
// },
|
|
607
|
+
abortController: new AbortController(),
|
|
1455
608
|
validate: () => {
|
|
1456
|
-
var
|
|
1457
|
-
|
|
609
|
+
var _store$parentMatch2;
|
|
1458
610
|
// Validate the search params and stabilize them
|
|
1459
|
-
const parentSearch = (
|
|
1460
|
-
|
|
611
|
+
const parentSearch = ((_store$parentMatch2 = store.parentMatch) == null ? void 0 : _store$parentMatch2.store.search) ?? router.store.currentLocation.search;
|
|
1461
612
|
try {
|
|
1462
|
-
const prevSearch =
|
|
613
|
+
const prevSearch = store.routeSearch;
|
|
1463
614
|
const validator = typeof routeMatch.options.validateSearch === 'object' ? routeMatch.options.validateSearch.parse : routeMatch.options.validateSearch;
|
|
1464
|
-
let nextSearch =
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
615
|
+
let nextSearch = sharedClone(prevSearch, (validator == null ? void 0 : validator(parentSearch)) ?? {});
|
|
616
|
+
batch(() => {
|
|
617
|
+
// Invalidate route matches when search param stability changes
|
|
618
|
+
if (prevSearch !== nextSearch) {
|
|
619
|
+
setStore(s => s.invalid = true);
|
|
620
|
+
}
|
|
1469
621
|
|
|
1470
|
-
|
|
1471
|
-
|
|
622
|
+
// TODO: Alright, do we need batch() here?
|
|
623
|
+
setStore(s => {
|
|
624
|
+
s.routeSearch = nextSearch;
|
|
625
|
+
s.search = sharedClone(parentSearch, {
|
|
626
|
+
...parentSearch,
|
|
627
|
+
...nextSearch
|
|
628
|
+
});
|
|
629
|
+
});
|
|
630
|
+
});
|
|
631
|
+
componentTypes.map(async type => {
|
|
632
|
+
const component = routeMatch.options[type];
|
|
633
|
+
if (typeof routeMatch.__[type] !== 'function') {
|
|
634
|
+
routeMatch.__[type] = component;
|
|
635
|
+
}
|
|
636
|
+
});
|
|
1472
637
|
} catch (err) {
|
|
1473
638
|
console.error(err);
|
|
1474
639
|
const error = new Error('Invalid search params found', {
|
|
1475
640
|
cause: err
|
|
1476
641
|
});
|
|
1477
642
|
error.code = 'INVALID_SEARCH_PARAMS';
|
|
1478
|
-
|
|
1479
|
-
|
|
643
|
+
setStore(s => {
|
|
644
|
+
s.status = 'error';
|
|
645
|
+
s.error = error;
|
|
646
|
+
});
|
|
1480
647
|
|
|
648
|
+
// Do not proceed with loading the route
|
|
1481
649
|
return;
|
|
1482
650
|
}
|
|
1483
651
|
}
|
|
1484
652
|
},
|
|
1485
653
|
cancel: () => {
|
|
1486
654
|
var _routeMatch$__$abortC;
|
|
1487
|
-
|
|
1488
655
|
(_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
|
|
1489
|
-
|
|
1490
|
-
routeMatch.__.cancelPending();
|
|
1491
656
|
},
|
|
1492
657
|
invalidate: () => {
|
|
1493
|
-
|
|
658
|
+
setStore(s => s.invalid = true);
|
|
1494
659
|
},
|
|
1495
660
|
hasLoaders: () => {
|
|
1496
|
-
return !!(route.options.loader ||
|
|
661
|
+
return !!(route.options.loader || componentTypes.some(d => {
|
|
662
|
+
var _route$options$d;
|
|
663
|
+
return (_route$options$d = route.options[d]) == null ? void 0 : _route$options$d.preload;
|
|
664
|
+
}));
|
|
1497
665
|
},
|
|
1498
666
|
load: async loaderOpts => {
|
|
1499
667
|
const now = Date.now();
|
|
1500
|
-
const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0;
|
|
668
|
+
const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0;
|
|
1501
669
|
|
|
670
|
+
// If this is a preload, add it to the preload cache
|
|
1502
671
|
if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
|
|
1503
672
|
// If the match is currently active, don't preload it
|
|
1504
|
-
if (router.
|
|
673
|
+
if (router.store.currentMatches.find(d => d.matchId === routeMatch.matchId)) {
|
|
1505
674
|
return;
|
|
1506
675
|
}
|
|
1507
|
-
|
|
1508
|
-
router.matchCache[routeMatch.matchId] = {
|
|
676
|
+
router.store.matchCache[routeMatch.matchId] = {
|
|
1509
677
|
gc: now + loaderOpts.gcMaxAge,
|
|
1510
678
|
match: routeMatch
|
|
1511
679
|
};
|
|
1512
|
-
}
|
|
1513
|
-
|
|
680
|
+
}
|
|
1514
681
|
|
|
1515
|
-
|
|
682
|
+
// If the match is invalid, errored or idle, trigger it to load
|
|
683
|
+
if (store.status === 'success' && store.isInvalid || store.status === 'error' || store.status === 'idle') {
|
|
1516
684
|
const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
|
|
1517
|
-
routeMatch.fetch({
|
|
685
|
+
await routeMatch.fetch({
|
|
1518
686
|
maxAge
|
|
1519
687
|
});
|
|
1520
688
|
}
|
|
1521
689
|
},
|
|
1522
690
|
fetch: async opts => {
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
}
|
|
1531
|
-
|
|
691
|
+
const loadId = '' + Date.now() + Math.random();
|
|
692
|
+
latestId = loadId;
|
|
693
|
+
const checkLatest = async () => {
|
|
694
|
+
if (loadId !== latestId) {
|
|
695
|
+
// warning(true, 'Data loader is out of date!')
|
|
696
|
+
return new Promise(() => {});
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
batch(() => {
|
|
700
|
+
// If the match was in an error state, set it
|
|
701
|
+
// to a loading state again. Otherwise, keep it
|
|
702
|
+
// as loading or resolved
|
|
703
|
+
if (store.status === 'idle') {
|
|
704
|
+
setStore(s => s.status = 'loading');
|
|
705
|
+
}
|
|
1532
706
|
|
|
1533
|
-
|
|
1534
|
-
|
|
707
|
+
// We started loading the route, so it's no longer invalid
|
|
708
|
+
setStore(s => s.invalid = false);
|
|
709
|
+
});
|
|
710
|
+
routeMatch.__.loadPromise = new Promise(async r => {
|
|
1535
711
|
// We are now fetching, even if it's in the background of a
|
|
1536
712
|
// resolved state
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
//
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
if (routeMatch.__[type]) {
|
|
1549
|
-
return;
|
|
1550
|
-
}
|
|
1551
|
-
|
|
1552
|
-
routeMatch.__[type] = await router.options.createElement(routeElement);
|
|
1553
|
-
}));
|
|
1554
|
-
})();
|
|
1555
|
-
|
|
1556
|
-
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
1557
|
-
try {
|
|
1558
|
-
var _ref, _ref2, _opts$maxAge;
|
|
1559
|
-
|
|
1560
|
-
if (routeMatch.options.loader) {
|
|
1561
|
-
const data = await routeMatch.options.loader({
|
|
1562
|
-
params: routeMatch.params,
|
|
1563
|
-
search: routeMatch.routeSearch,
|
|
1564
|
-
signal: routeMatch.__.abortController.signal
|
|
1565
|
-
});
|
|
1566
|
-
|
|
1567
|
-
if (id !== routeMatch.__.latestId) {
|
|
1568
|
-
return routeMatch.__.loaderPromise;
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
|
-
routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
|
|
1572
|
-
}
|
|
1573
|
-
|
|
1574
|
-
routeMatch.error = undefined;
|
|
1575
|
-
routeMatch.status = 'success';
|
|
1576
|
-
routeMatch.updatedAt = Date.now();
|
|
1577
|
-
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);
|
|
1578
|
-
} catch (err) {
|
|
1579
|
-
if (id !== routeMatch.__.latestId) {
|
|
1580
|
-
return routeMatch.__.loaderPromise;
|
|
1581
|
-
}
|
|
1582
|
-
|
|
1583
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
1584
|
-
console.error(err);
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
routeMatch.error = err;
|
|
1588
|
-
routeMatch.status = 'error';
|
|
1589
|
-
routeMatch.updatedAt = Date.now();
|
|
713
|
+
setStore(s => s.isFetching = true);
|
|
714
|
+
resolve = r;
|
|
715
|
+
componentsPromise = (async () => {
|
|
716
|
+
// then run all component and data loaders in parallel
|
|
717
|
+
// For each component type, potentially load it asynchronously
|
|
718
|
+
|
|
719
|
+
await Promise.all(componentTypes.map(async type => {
|
|
720
|
+
var _routeMatch$__$type;
|
|
721
|
+
const component = routeMatch.options[type];
|
|
722
|
+
if ((_routeMatch$__$type = routeMatch.__[type]) != null && _routeMatch$__$type.preload) {
|
|
723
|
+
routeMatch.__[type] = await router.options.loadComponent(component);
|
|
1590
724
|
}
|
|
1591
|
-
});
|
|
1592
|
-
|
|
725
|
+
}));
|
|
726
|
+
})();
|
|
727
|
+
dataPromise = Promise.resolve().then(async () => {
|
|
1593
728
|
try {
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
}
|
|
1599
|
-
|
|
1600
|
-
if (routeMatch.__.pendingMinPromise) {
|
|
1601
|
-
await routeMatch.__.pendingMinPromise;
|
|
1602
|
-
delete routeMatch.__.pendingMinPromise;
|
|
729
|
+
if (routeMatch.options.loader) {
|
|
730
|
+
const data = await router.loadMatchData(routeMatch);
|
|
731
|
+
await checkLatest();
|
|
732
|
+
setLoaderData(data);
|
|
1603
733
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
734
|
+
setStore(s => {
|
|
735
|
+
s.error = undefined;
|
|
736
|
+
s.status = 'success';
|
|
737
|
+
s.updatedAt = Date.now();
|
|
738
|
+
s.invalidAt = s.updatedAt + ((opts == null ? void 0 : opts.maxAge) ?? routeMatch.options.loaderMaxAge ?? router.options.defaultLoaderMaxAge ?? 0);
|
|
739
|
+
});
|
|
740
|
+
return store.routeLoaderData;
|
|
741
|
+
} catch (err) {
|
|
742
|
+
await checkLatest();
|
|
743
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
744
|
+
console.error(err);
|
|
1607
745
|
}
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
routeMatch.__.notify();
|
|
746
|
+
setStore(s => {
|
|
747
|
+
s.error = err;
|
|
748
|
+
s.status = 'error';
|
|
749
|
+
s.updatedAt = Date.now();
|
|
750
|
+
});
|
|
751
|
+
throw err;
|
|
1615
752
|
}
|
|
1616
|
-
})
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
753
|
+
});
|
|
754
|
+
const after = async () => {
|
|
755
|
+
await checkLatest();
|
|
756
|
+
setStore(s => s.isFetching = false);
|
|
757
|
+
delete routeMatch.__.loadPromise;
|
|
758
|
+
resolve();
|
|
759
|
+
};
|
|
760
|
+
try {
|
|
761
|
+
await Promise.all([componentsPromise, dataPromise.catch(() => {})]);
|
|
762
|
+
after();
|
|
763
|
+
} catch {
|
|
764
|
+
after();
|
|
1623
765
|
}
|
|
1624
|
-
|
|
1625
|
-
delete routeMatch.__.loaderPromise;
|
|
1626
766
|
});
|
|
1627
|
-
|
|
767
|
+
await routeMatch.__.loadPromise;
|
|
768
|
+
await checkLatest();
|
|
1628
769
|
}
|
|
1629
|
-
}
|
|
1630
|
-
|
|
770
|
+
};
|
|
1631
771
|
if (!routeMatch.hasLoaders()) {
|
|
1632
|
-
|
|
772
|
+
setStore(s => s.status = 'success');
|
|
1633
773
|
}
|
|
1634
|
-
|
|
1635
774
|
return routeMatch;
|
|
1636
775
|
}
|
|
1637
776
|
|
|
@@ -1642,221 +781,347 @@ function parseSearchWith(parser) {
|
|
|
1642
781
|
if (searchStr.substring(0, 1) === '?') {
|
|
1643
782
|
searchStr = searchStr.substring(1);
|
|
1644
783
|
}
|
|
784
|
+
let query = decode(searchStr);
|
|
1645
785
|
|
|
1646
|
-
|
|
1647
|
-
|
|
786
|
+
// Try to parse any query params that might be json
|
|
1648
787
|
for (let key in query) {
|
|
1649
788
|
const value = query[key];
|
|
1650
|
-
|
|
1651
789
|
if (typeof value === 'string') {
|
|
1652
790
|
try {
|
|
1653
791
|
query[key] = parser(value);
|
|
1654
|
-
} catch (err) {
|
|
792
|
+
} catch (err) {
|
|
793
|
+
//
|
|
1655
794
|
}
|
|
1656
795
|
}
|
|
1657
796
|
}
|
|
1658
|
-
|
|
1659
797
|
return query;
|
|
1660
798
|
};
|
|
1661
799
|
}
|
|
1662
800
|
function stringifySearchWith(stringify) {
|
|
1663
801
|
return search => {
|
|
1664
|
-
search =
|
|
1665
|
-
|
|
802
|
+
search = {
|
|
803
|
+
...search
|
|
804
|
+
};
|
|
1666
805
|
if (search) {
|
|
1667
806
|
Object.keys(search).forEach(key => {
|
|
1668
807
|
const val = search[key];
|
|
1669
|
-
|
|
1670
808
|
if (typeof val === 'undefined' || val === undefined) {
|
|
1671
809
|
delete search[key];
|
|
1672
810
|
} else if (val && typeof val === 'object' && val !== null) {
|
|
1673
811
|
try {
|
|
1674
812
|
search[key] = stringify(val);
|
|
1675
|
-
} catch (err) {
|
|
813
|
+
} catch (err) {
|
|
814
|
+
// silent
|
|
1676
815
|
}
|
|
1677
816
|
}
|
|
1678
817
|
});
|
|
1679
818
|
}
|
|
1680
|
-
|
|
1681
819
|
const searchStr = encode(search).toString();
|
|
1682
|
-
return searchStr ?
|
|
820
|
+
return searchStr ? `?${searchStr}` : '';
|
|
1683
821
|
};
|
|
1684
822
|
}
|
|
1685
823
|
|
|
1686
824
|
var _window$document;
|
|
1687
825
|
// Detect if we're in the DOM
|
|
1688
|
-
const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement);
|
|
826
|
+
const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement);
|
|
1689
827
|
|
|
828
|
+
// This is the default history object if none is defined
|
|
1690
829
|
const createDefaultHistory = () => isServer ? createMemoryHistory() : createBrowserHistory();
|
|
1691
|
-
|
|
830
|
+
function getInitialRouterState() {
|
|
831
|
+
return {
|
|
832
|
+
status: 'idle',
|
|
833
|
+
latestLocation: null,
|
|
834
|
+
currentLocation: null,
|
|
835
|
+
currentMatches: [],
|
|
836
|
+
actions: {},
|
|
837
|
+
loaders: {},
|
|
838
|
+
lastUpdated: Date.now(),
|
|
839
|
+
matchCache: {},
|
|
840
|
+
get isFetching() {
|
|
841
|
+
return this.status === 'loading' || this.currentMatches.some(d => d.store.isFetching);
|
|
842
|
+
},
|
|
843
|
+
get isPreloading() {
|
|
844
|
+
return Object.values(this.matchCache).some(d => d.match.store.isFetching && !this.currentMatches.find(dd => dd.matchId === d.match.matchId));
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
}
|
|
1692
848
|
function createRouter(userOptions) {
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
|
|
1696
|
-
|
|
1697
|
-
const originalOptions = _extends({
|
|
849
|
+
const originalOptions = {
|
|
1698
850
|
defaultLoaderGcMaxAge: 5 * 60 * 1000,
|
|
1699
851
|
defaultLoaderMaxAge: 0,
|
|
1700
852
|
defaultPreloadMaxAge: 2000,
|
|
1701
|
-
defaultPreloadDelay: 50
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
853
|
+
defaultPreloadDelay: 50,
|
|
854
|
+
context: undefined,
|
|
855
|
+
...userOptions,
|
|
856
|
+
stringifySearch: (userOptions == null ? void 0 : userOptions.stringifySearch) ?? defaultStringifySearch,
|
|
857
|
+
parseSearch: (userOptions == null ? void 0 : userOptions.parseSearch) ?? defaultParseSearch
|
|
858
|
+
};
|
|
859
|
+
const [store, setStore] = createStore(getInitialRouterState());
|
|
860
|
+
let navigationPromise;
|
|
861
|
+
let startedLoadingAt = Date.now();
|
|
862
|
+
let resolveNavigation = () => {};
|
|
863
|
+
function onFocus() {
|
|
864
|
+
router.load();
|
|
865
|
+
}
|
|
866
|
+
function buildRouteTree(rootRouteConfig) {
|
|
867
|
+
const recurseRoutes = (routeConfigs, parent) => {
|
|
868
|
+
return routeConfigs.map((routeConfig, i) => {
|
|
869
|
+
const routeOptions = routeConfig.options;
|
|
870
|
+
const route = createRoute(routeConfig, routeOptions, i, parent, router);
|
|
871
|
+
const existingRoute = router.routesById[route.routeId];
|
|
872
|
+
if (existingRoute) {
|
|
873
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
874
|
+
console.warn(`Duplicate routes found with id: ${String(route.routeId)}`, router.routesById, route);
|
|
875
|
+
}
|
|
876
|
+
throw new Error();
|
|
877
|
+
}
|
|
878
|
+
router.routesById[route.routeId] = route;
|
|
879
|
+
const children = routeConfig.children;
|
|
880
|
+
route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
|
|
881
|
+
return route;
|
|
882
|
+
});
|
|
883
|
+
};
|
|
884
|
+
const routes = recurseRoutes([rootRouteConfig]);
|
|
885
|
+
return routes[0];
|
|
886
|
+
}
|
|
887
|
+
function parseLocation(location, previousLocation) {
|
|
888
|
+
const parsedSearch = router.options.parseSearch(location.search);
|
|
889
|
+
return {
|
|
890
|
+
pathname: location.pathname,
|
|
891
|
+
searchStr: location.search,
|
|
892
|
+
search: sharedClone(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
|
|
893
|
+
hash: location.hash.split('#').reverse()[0] ?? '',
|
|
894
|
+
href: `${location.pathname}${location.search}${location.hash}`,
|
|
895
|
+
state: location.state,
|
|
896
|
+
key: location.key
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
function navigate(location) {
|
|
900
|
+
const next = router.buildNext(location);
|
|
901
|
+
return commitLocation(next, location.replace);
|
|
902
|
+
}
|
|
903
|
+
function buildLocation(dest) {
|
|
904
|
+
var _last, _dest$__preSearchFilt, _dest$__preSearchFilt2, _dest$__postSearchFil;
|
|
905
|
+
if (dest === void 0) {
|
|
906
|
+
dest = {};
|
|
907
|
+
}
|
|
908
|
+
const fromPathname = dest.fromCurrent ? store.latestLocation.pathname : dest.from ?? store.latestLocation.pathname;
|
|
909
|
+
let pathname = resolvePath(router.basepath ?? '/', fromPathname, `${dest.to ?? '.'}`);
|
|
910
|
+
const fromMatches = router.matchRoutes(store.latestLocation.pathname, {
|
|
911
|
+
strictParseParams: true
|
|
912
|
+
});
|
|
913
|
+
const toMatches = router.matchRoutes(pathname);
|
|
914
|
+
const prevParams = {
|
|
915
|
+
...((_last = last(fromMatches)) == null ? void 0 : _last.params)
|
|
916
|
+
};
|
|
917
|
+
let nextParams = (dest.params ?? true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
918
|
+
if (nextParams) {
|
|
919
|
+
toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
920
|
+
Object.assign({}, nextParams, fn(nextParams));
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
pathname = interpolatePath(pathname, nextParams ?? {});
|
|
924
|
+
|
|
925
|
+
// Pre filters first
|
|
926
|
+
const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), store.latestLocation.search) : store.latestLocation.search;
|
|
927
|
+
|
|
928
|
+
// Then the link/navigate function
|
|
929
|
+
const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
|
|
930
|
+
: dest.search ? functionalUpdate(dest.search, preFilteredSearch) ?? {} // Updater
|
|
931
|
+
: (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
|
|
932
|
+
: {};
|
|
933
|
+
|
|
934
|
+
// Then post filters
|
|
935
|
+
const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
936
|
+
const search = sharedClone(store.latestLocation.search, postFilteredSearch);
|
|
937
|
+
const searchStr = router.options.stringifySearch(search);
|
|
938
|
+
let hash = dest.hash === true ? store.latestLocation.hash : functionalUpdate(dest.hash, store.latestLocation.hash);
|
|
939
|
+
hash = hash ? `#${hash}` : '';
|
|
940
|
+
return {
|
|
941
|
+
pathname,
|
|
942
|
+
search,
|
|
943
|
+
searchStr,
|
|
944
|
+
state: store.latestLocation.state,
|
|
945
|
+
hash,
|
|
946
|
+
href: `${pathname}${searchStr}${hash}`,
|
|
947
|
+
key: dest.key
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
function commitLocation(next, replace) {
|
|
951
|
+
const id = '' + Date.now() + Math.random();
|
|
952
|
+
let nextAction = 'replace';
|
|
953
|
+
if (!replace) {
|
|
954
|
+
nextAction = 'push';
|
|
955
|
+
}
|
|
956
|
+
const isSameUrl = parseLocation(router.history.location).href === next.href;
|
|
957
|
+
if (isSameUrl && !next.key) {
|
|
958
|
+
nextAction = 'replace';
|
|
959
|
+
}
|
|
960
|
+
router.history[nextAction]({
|
|
961
|
+
pathname: next.pathname,
|
|
962
|
+
hash: next.hash,
|
|
963
|
+
search: next.searchStr
|
|
964
|
+
}, {
|
|
965
|
+
id,
|
|
966
|
+
...next.state
|
|
967
|
+
});
|
|
968
|
+
return navigationPromise = new Promise(resolve => {
|
|
969
|
+
const previousNavigationResolve = resolveNavigation;
|
|
970
|
+
resolveNavigation = () => {
|
|
971
|
+
previousNavigationResolve();
|
|
972
|
+
resolve();
|
|
973
|
+
};
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
const router = {
|
|
977
|
+
types: undefined,
|
|
978
|
+
// public api
|
|
979
|
+
history: (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory(),
|
|
980
|
+
store,
|
|
981
|
+
setStore,
|
|
1709
982
|
options: originalOptions,
|
|
1710
|
-
listeners: [],
|
|
1711
|
-
removeActionQueue: [],
|
|
1712
|
-
// Resolved after construction
|
|
1713
983
|
basepath: '',
|
|
1714
984
|
routeTree: undefined,
|
|
1715
985
|
routesById: {},
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
//
|
|
1719
|
-
navigationPromise: Promise.resolve(),
|
|
1720
|
-
resolveNavigation: () => {},
|
|
1721
|
-
matchCache: {},
|
|
1722
|
-
state: {
|
|
1723
|
-
status: 'idle',
|
|
1724
|
-
location: null,
|
|
1725
|
-
matches: [],
|
|
1726
|
-
actions: {},
|
|
1727
|
-
loaders: {},
|
|
1728
|
-
loaderData: {},
|
|
1729
|
-
lastUpdated: Date.now(),
|
|
1730
|
-
isFetching: false,
|
|
1731
|
-
isPreloading: false
|
|
1732
|
-
},
|
|
1733
|
-
startedLoadingAt: Date.now(),
|
|
1734
|
-
subscribe: listener => {
|
|
1735
|
-
router.listeners.push(listener);
|
|
1736
|
-
return () => {
|
|
1737
|
-
router.listeners = router.listeners.filter(x => x !== listener);
|
|
1738
|
-
};
|
|
986
|
+
reset: () => {
|
|
987
|
+
setStore(s => Object.assign(s, getInitialRouterState()));
|
|
1739
988
|
},
|
|
1740
989
|
getRoute: id => {
|
|
1741
990
|
return router.routesById[id];
|
|
1742
991
|
},
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
992
|
+
dehydrate: () => {
|
|
993
|
+
return {
|
|
994
|
+
store: {
|
|
995
|
+
...pick(store, ['latestLocation', 'currentLocation', 'status', 'lastUpdated']),
|
|
996
|
+
currentMatches: store.currentMatches.map(match => ({
|
|
997
|
+
matchId: match.matchId,
|
|
998
|
+
store: pick(match.store, ['status', 'routeLoaderData', 'isInvalid', 'invalidAt'])
|
|
999
|
+
}))
|
|
1000
|
+
},
|
|
1001
|
+
context: router.options.context
|
|
1002
|
+
};
|
|
1003
|
+
},
|
|
1004
|
+
hydrate: dehydratedRouter => {
|
|
1005
|
+
setStore(s => {
|
|
1006
|
+
// Update the context TODO: make this part of state?
|
|
1007
|
+
router.options.context = dehydratedRouter.context;
|
|
1008
|
+
|
|
1009
|
+
// Match the routes
|
|
1010
|
+
const currentMatches = router.matchRoutes(dehydratedRouter.store.latestLocation.pathname, {
|
|
1011
|
+
strictParseParams: true
|
|
1012
|
+
});
|
|
1013
|
+
currentMatches.forEach((match, index) => {
|
|
1014
|
+
const dehydratedMatch = dehydratedRouter.store.currentMatches[index];
|
|
1015
|
+
invariant(dehydratedMatch && dehydratedMatch.matchId === match.matchId, 'Oh no! There was a hydration mismatch when attempting to restore the state of the router! 😬');
|
|
1016
|
+
Object.assign(match, dehydratedMatch);
|
|
1017
|
+
});
|
|
1018
|
+
currentMatches.forEach(match => match.__.validate());
|
|
1019
|
+
Object.assign(s, {
|
|
1020
|
+
...dehydratedRouter.store,
|
|
1021
|
+
currentMatches
|
|
1022
|
+
});
|
|
1747
1023
|
});
|
|
1748
|
-
cascadeLoaderData(router.state.matches);
|
|
1749
|
-
router.listeners.forEach(listener => listener(router));
|
|
1750
1024
|
},
|
|
1751
1025
|
mount: () => {
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
router.__.commitLocation(next, true);
|
|
1762
|
-
} else {
|
|
1763
|
-
router.loadLocation();
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
const unsub = history.listen(event => {
|
|
1767
|
-
router.loadLocation(router.__.parseLocation(event.location, router.location));
|
|
1768
|
-
}); // addEventListener does not exist in React Native, but window does
|
|
1769
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1026
|
+
// Mount only does anything on the client
|
|
1027
|
+
if (!isServer) {
|
|
1028
|
+
// If the router matches are empty, load the matches
|
|
1029
|
+
if (!store.currentMatches.length) {
|
|
1030
|
+
router.load();
|
|
1031
|
+
}
|
|
1032
|
+
const unsub = router.history.listen(event => {
|
|
1033
|
+
router.load(parseLocation(event.location, store.latestLocation));
|
|
1034
|
+
});
|
|
1770
1035
|
|
|
1771
|
-
|
|
1772
|
-
//
|
|
1773
|
-
|
|
1774
|
-
window.addEventListener
|
|
1036
|
+
// addEventListener does not exist in React Native, but window does
|
|
1037
|
+
// In the future, we might need to invert control here for more adapters
|
|
1038
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1039
|
+
if (window.addEventListener) {
|
|
1040
|
+
// Listen to visibilitychange and focus
|
|
1041
|
+
window.addEventListener('visibilitychange', onFocus, false);
|
|
1042
|
+
window.addEventListener('focus', onFocus, false);
|
|
1043
|
+
}
|
|
1044
|
+
return () => {
|
|
1045
|
+
unsub();
|
|
1046
|
+
if (window.removeEventListener) {
|
|
1047
|
+
// Be sure to unsubscribe if a new handler is set
|
|
1048
|
+
window.removeEventListener('visibilitychange', onFocus);
|
|
1049
|
+
window.removeEventListener('focus', onFocus);
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1775
1052
|
}
|
|
1776
|
-
|
|
1777
|
-
return () => {
|
|
1778
|
-
unsub(); // Be sure to unsubscribe if a new handler is set
|
|
1779
|
-
|
|
1780
|
-
window.removeEventListener('visibilitychange', router.onFocus);
|
|
1781
|
-
window.removeEventListener('focus', router.onFocus);
|
|
1782
|
-
};
|
|
1783
|
-
},
|
|
1784
|
-
onFocus: () => {
|
|
1785
|
-
router.loadLocation();
|
|
1053
|
+
return () => {};
|
|
1786
1054
|
},
|
|
1787
1055
|
update: opts => {
|
|
1056
|
+
const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
|
|
1057
|
+
if (!store.latestLocation || newHistory) {
|
|
1058
|
+
if (opts != null && opts.history) {
|
|
1059
|
+
router.history = opts.history;
|
|
1060
|
+
}
|
|
1061
|
+
setStore(s => {
|
|
1062
|
+
s.latestLocation = parseLocation(router.history.location);
|
|
1063
|
+
s.currentLocation = s.latestLocation;
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1788
1066
|
Object.assign(router.options, opts);
|
|
1789
1067
|
const {
|
|
1790
1068
|
basepath,
|
|
1791
1069
|
routeConfig
|
|
1792
1070
|
} = router.options;
|
|
1793
|
-
router.basepath =
|
|
1794
|
-
|
|
1071
|
+
router.basepath = `/${trimPath(basepath ?? '') ?? ''}`;
|
|
1795
1072
|
if (routeConfig) {
|
|
1796
1073
|
router.routesById = {};
|
|
1797
|
-
router.routeTree =
|
|
1074
|
+
router.routeTree = buildRouteTree(routeConfig);
|
|
1798
1075
|
}
|
|
1799
|
-
|
|
1800
1076
|
return router;
|
|
1801
1077
|
},
|
|
1802
1078
|
cancelMatches: () => {
|
|
1803
|
-
|
|
1804
|
-
[...router.state.matches, ...((_router$state$pending = (_router$state$pending2 = router.state.pending) == null ? void 0 : _router$state$pending2.matches) != null ? _router$state$pending : [])].forEach(match => {
|
|
1079
|
+
[...store.currentMatches, ...(store.pendingMatches || [])].forEach(match => {
|
|
1805
1080
|
match.cancel();
|
|
1806
1081
|
});
|
|
1807
1082
|
},
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
} = _ref;
|
|
1823
|
-
|
|
1824
|
-
if (router.state.currentAction === actionState) {
|
|
1825
|
-
router.state.currentAction = undefined;
|
|
1826
|
-
}
|
|
1827
|
-
|
|
1828
|
-
if (action.current === actionState) {
|
|
1829
|
-
action.current = undefined;
|
|
1083
|
+
load: async next => {
|
|
1084
|
+
let now = Date.now();
|
|
1085
|
+
const startedAt = now;
|
|
1086
|
+
startedLoadingAt = startedAt;
|
|
1087
|
+
|
|
1088
|
+
// Cancel any pending matches
|
|
1089
|
+
router.cancelMatches();
|
|
1090
|
+
let matches;
|
|
1091
|
+
batch(() => {
|
|
1092
|
+
if (next) {
|
|
1093
|
+
// Ingest the new location
|
|
1094
|
+
setStore(s => {
|
|
1095
|
+
s.latestLocation = next;
|
|
1096
|
+
});
|
|
1830
1097
|
}
|
|
1831
|
-
});
|
|
1832
|
-
router.removeActionQueue = []; // Cancel any pending matches
|
|
1833
|
-
|
|
1834
|
-
router.cancelMatches(); // Match the routes
|
|
1835
|
-
|
|
1836
|
-
const matches = router.matchRoutes(location.pathname, {
|
|
1837
|
-
strictParseParams: true
|
|
1838
|
-
});
|
|
1839
|
-
router.state = _extends({}, router.state, {
|
|
1840
|
-
pending: {
|
|
1841
|
-
matches: matches,
|
|
1842
|
-
location: router.location
|
|
1843
|
-
},
|
|
1844
|
-
status: 'loading'
|
|
1845
|
-
});
|
|
1846
|
-
router.notify(); // Load the matches
|
|
1847
1098
|
|
|
1848
|
-
|
|
1849
|
-
|
|
1099
|
+
// Match the routes
|
|
1100
|
+
matches = router.matchRoutes(store.latestLocation.pathname, {
|
|
1101
|
+
strictParseParams: true
|
|
1102
|
+
});
|
|
1103
|
+
console.log('set loading', matches);
|
|
1104
|
+
setStore(s => {
|
|
1105
|
+
s.status = 'loading';
|
|
1106
|
+
s.pendingMatches = matches;
|
|
1107
|
+
s.pendingLocation = store.latestLocation;
|
|
1108
|
+
});
|
|
1850
1109
|
});
|
|
1851
1110
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1111
|
+
// Load the matches
|
|
1112
|
+
try {
|
|
1113
|
+
await router.loadMatches(matches);
|
|
1114
|
+
} catch (err) {
|
|
1115
|
+
console.log(err);
|
|
1116
|
+
invariant(false, 'Matches failed to load due to error above ☝️. Navigation cancelled!');
|
|
1855
1117
|
}
|
|
1856
|
-
|
|
1857
|
-
|
|
1118
|
+
if (startedLoadingAt !== startedAt) {
|
|
1119
|
+
// Ignore side-effects of outdated side-effects
|
|
1120
|
+
return navigationPromise;
|
|
1121
|
+
}
|
|
1122
|
+
const previousMatches = store.currentMatches;
|
|
1858
1123
|
const exiting = [],
|
|
1859
|
-
|
|
1124
|
+
staying = [];
|
|
1860
1125
|
previousMatches.forEach(d => {
|
|
1861
1126
|
if (matches.find(dd => dd.matchId === d.matchId)) {
|
|
1862
1127
|
staying.push(d);
|
|
@@ -1864,24 +1129,24 @@ function createRouter(userOptions) {
|
|
|
1864
1129
|
exiting.push(d);
|
|
1865
1130
|
}
|
|
1866
1131
|
});
|
|
1867
|
-
const
|
|
1132
|
+
const entering = matches.filter(d => {
|
|
1133
|
+
return !previousMatches.find(dd => dd.matchId === d.matchId);
|
|
1134
|
+
});
|
|
1135
|
+
now = Date.now();
|
|
1868
1136
|
exiting.forEach(d => {
|
|
1869
|
-
var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
|
|
1870
|
-
|
|
1871
1137
|
d.__.onExit == null ? void 0 : d.__.onExit({
|
|
1872
1138
|
params: d.params,
|
|
1873
|
-
search: d.routeSearch
|
|
1874
|
-
});
|
|
1139
|
+
search: d.store.routeSearch
|
|
1140
|
+
});
|
|
1875
1141
|
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
d.
|
|
1142
|
+
// Clear idle error states when match leaves
|
|
1143
|
+
if (d.store.status === 'error' && !d.store.isFetching) {
|
|
1144
|
+
d.store.status = 'idle';
|
|
1145
|
+
d.store.error = undefined;
|
|
1879
1146
|
}
|
|
1880
|
-
|
|
1881
|
-
const gc = Math.max((_ref2 = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref2 : 0, (_ref3 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0);
|
|
1882
|
-
|
|
1147
|
+
const gc = Math.max(d.options.loaderGcMaxAge ?? router.options.defaultLoaderGcMaxAge ?? 0, d.options.loaderMaxAge ?? router.options.defaultLoaderMaxAge ?? 0);
|
|
1883
1148
|
if (gc > 0) {
|
|
1884
|
-
|
|
1149
|
+
store.matchCache[d.matchId] = {
|
|
1885
1150
|
gc: gc == Infinity ? Number.MAX_SAFE_INTEGER : now + gc,
|
|
1886
1151
|
match: d
|
|
1887
1152
|
};
|
|
@@ -1890,62 +1155,65 @@ function createRouter(userOptions) {
|
|
|
1890
1155
|
staying.forEach(d => {
|
|
1891
1156
|
d.options.onTransition == null ? void 0 : d.options.onTransition({
|
|
1892
1157
|
params: d.params,
|
|
1893
|
-
search: d.routeSearch
|
|
1158
|
+
search: d.store.routeSearch
|
|
1894
1159
|
});
|
|
1895
1160
|
});
|
|
1896
|
-
const entering = matches.filter(d => {
|
|
1897
|
-
return !previousMatches.find(dd => dd.matchId === d.matchId);
|
|
1898
|
-
});
|
|
1899
1161
|
entering.forEach(d => {
|
|
1900
|
-
d.__.onExit = d.options.
|
|
1162
|
+
d.__.onExit = d.options.onLoaded == null ? void 0 : d.options.onLoaded({
|
|
1901
1163
|
params: d.params,
|
|
1902
|
-
search: d.search
|
|
1164
|
+
search: d.store.search
|
|
1903
1165
|
});
|
|
1904
|
-
delete
|
|
1166
|
+
delete store.matchCache[d.matchId];
|
|
1905
1167
|
});
|
|
1906
|
-
|
|
1907
|
-
if (matches.some(d => d.status === 'loading')) {
|
|
1908
|
-
router.notify();
|
|
1909
|
-
await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
|
|
1910
|
-
}
|
|
1911
|
-
|
|
1912
|
-
if (router.startedLoadingAt !== id) {
|
|
1168
|
+
if (startedLoadingAt !== startedAt) {
|
|
1913
1169
|
// Ignore side-effects of match loading
|
|
1914
1170
|
return;
|
|
1915
1171
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1172
|
+
matches.forEach(match => {
|
|
1173
|
+
// Clear actions
|
|
1174
|
+
if (match.action) {
|
|
1175
|
+
// TODO: Check reactivity here
|
|
1176
|
+
match.action.current = undefined;
|
|
1177
|
+
match.action.submissions = [];
|
|
1178
|
+
}
|
|
1922
1179
|
});
|
|
1923
|
-
|
|
1924
|
-
|
|
1180
|
+
setStore(s => {
|
|
1181
|
+
console.log('set', matches);
|
|
1182
|
+
Object.assign(s, {
|
|
1183
|
+
status: 'idle',
|
|
1184
|
+
currentLocation: store.latestLocation,
|
|
1185
|
+
currentMatches: matches,
|
|
1186
|
+
pendingLocation: undefined,
|
|
1187
|
+
pendingMatches: undefined
|
|
1188
|
+
});
|
|
1189
|
+
});
|
|
1190
|
+
resolveNavigation();
|
|
1925
1191
|
},
|
|
1926
1192
|
cleanMatchCache: () => {
|
|
1927
1193
|
const now = Date.now();
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
if (entry.match.status === 'loading') {
|
|
1932
|
-
return;
|
|
1933
|
-
} // Do not remove successful matches that are still valid
|
|
1194
|
+
setStore(s => {
|
|
1195
|
+
Object.keys(s.matchCache).forEach(matchId => {
|
|
1196
|
+
const entry = s.matchCache[matchId];
|
|
1934
1197
|
|
|
1198
|
+
// Don't remove loading matches
|
|
1199
|
+
if (entry.match.store.status === 'loading') {
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1935
1202
|
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1203
|
+
// Do not remove successful matches that are still valid
|
|
1204
|
+
if (entry.gc > 0 && entry.gc > now) {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1940
1207
|
|
|
1941
|
-
|
|
1208
|
+
// Everything else gets removed
|
|
1209
|
+
delete s.matchCache[matchId];
|
|
1210
|
+
});
|
|
1942
1211
|
});
|
|
1943
1212
|
},
|
|
1944
|
-
loadRoute: async function
|
|
1213
|
+
loadRoute: async function (navigateOpts) {
|
|
1945
1214
|
if (navigateOpts === void 0) {
|
|
1946
|
-
navigateOpts =
|
|
1215
|
+
navigateOpts = store.latestLocation;
|
|
1947
1216
|
}
|
|
1948
|
-
|
|
1949
1217
|
const next = router.buildNext(navigateOpts);
|
|
1950
1218
|
const matches = router.matchRoutes(next.pathname, {
|
|
1951
1219
|
strictParseParams: true
|
|
@@ -1953,143 +1221,176 @@ function createRouter(userOptions) {
|
|
|
1953
1221
|
await router.loadMatches(matches);
|
|
1954
1222
|
return matches;
|
|
1955
1223
|
},
|
|
1956
|
-
preloadRoute: async function
|
|
1957
|
-
var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
|
|
1958
|
-
|
|
1224
|
+
preloadRoute: async function (navigateOpts, loaderOpts) {
|
|
1959
1225
|
if (navigateOpts === void 0) {
|
|
1960
|
-
navigateOpts =
|
|
1226
|
+
navigateOpts = store.latestLocation;
|
|
1961
1227
|
}
|
|
1962
|
-
|
|
1963
1228
|
const next = router.buildNext(navigateOpts);
|
|
1964
1229
|
const matches = router.matchRoutes(next.pathname, {
|
|
1965
1230
|
strictParseParams: true
|
|
1966
1231
|
});
|
|
1967
1232
|
await router.loadMatches(matches, {
|
|
1968
1233
|
preload: true,
|
|
1969
|
-
maxAge:
|
|
1970
|
-
gcMaxAge:
|
|
1234
|
+
maxAge: loaderOpts.maxAge ?? router.options.defaultPreloadMaxAge ?? router.options.defaultLoaderMaxAge ?? 0,
|
|
1235
|
+
gcMaxAge: loaderOpts.gcMaxAge ?? router.options.defaultPreloadGcMaxAge ?? router.options.defaultLoaderGcMaxAge ?? 0
|
|
1971
1236
|
});
|
|
1972
1237
|
return matches;
|
|
1973
1238
|
},
|
|
1974
1239
|
matchRoutes: (pathname, opts) => {
|
|
1975
|
-
var _router$state$pending3, _router$state$pending4;
|
|
1976
|
-
|
|
1977
1240
|
router.cleanMatchCache();
|
|
1978
1241
|
const matches = [];
|
|
1979
|
-
|
|
1980
1242
|
if (!router.routeTree) {
|
|
1981
1243
|
return matches;
|
|
1982
1244
|
}
|
|
1983
|
-
|
|
1984
|
-
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 : [])];
|
|
1985
|
-
|
|
1245
|
+
const existingMatches = [...store.currentMatches, ...(store.pendingMatches ?? [])];
|
|
1986
1246
|
const recurse = async routes => {
|
|
1987
|
-
var
|
|
1988
|
-
|
|
1247
|
+
var _foundRoute$childRout;
|
|
1989
1248
|
const parentMatch = last(matches);
|
|
1990
|
-
let params = (
|
|
1991
|
-
const filteredRoutes = (
|
|
1249
|
+
let params = (parentMatch == null ? void 0 : parentMatch.params) ?? {};
|
|
1250
|
+
const filteredRoutes = (router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) ?? routes;
|
|
1992
1251
|
let foundRoutes = [];
|
|
1993
|
-
|
|
1994
1252
|
const findMatchInRoutes = (parentRoutes, routes) => {
|
|
1995
1253
|
routes.some(route => {
|
|
1996
|
-
var _route$childRoutes, _route$childRoutes2
|
|
1997
|
-
|
|
1254
|
+
var _route$childRoutes, _route$childRoutes2;
|
|
1998
1255
|
if (!route.routePath && (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length) {
|
|
1999
1256
|
return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
|
|
2000
1257
|
}
|
|
2001
|
-
|
|
2002
1258
|
const fuzzy = !!(route.routePath !== '/' || (_route$childRoutes2 = route.childRoutes) != null && _route$childRoutes2.length);
|
|
2003
|
-
const matchParams = matchPathname(pathname, {
|
|
1259
|
+
const matchParams = matchPathname(router.basepath, pathname, {
|
|
2004
1260
|
to: route.fullPath,
|
|
2005
1261
|
fuzzy,
|
|
2006
|
-
caseSensitive:
|
|
1262
|
+
caseSensitive: route.options.caseSensitive ?? router.options.caseSensitive
|
|
2007
1263
|
});
|
|
2008
|
-
|
|
2009
1264
|
if (matchParams) {
|
|
2010
1265
|
let parsedParams;
|
|
2011
|
-
|
|
2012
1266
|
try {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
|
|
1267
|
+
parsedParams = (route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) ?? matchParams;
|
|
2016
1268
|
} catch (err) {
|
|
2017
1269
|
if (opts != null && opts.strictParseParams) {
|
|
2018
1270
|
throw err;
|
|
2019
1271
|
}
|
|
2020
1272
|
}
|
|
2021
|
-
|
|
2022
|
-
|
|
1273
|
+
params = {
|
|
1274
|
+
...params,
|
|
1275
|
+
...parsedParams
|
|
1276
|
+
};
|
|
2023
1277
|
}
|
|
2024
|
-
|
|
2025
1278
|
if (!!matchParams) {
|
|
2026
1279
|
foundRoutes = [...parentRoutes, route];
|
|
2027
1280
|
}
|
|
2028
|
-
|
|
2029
1281
|
return !!foundRoutes.length;
|
|
2030
1282
|
});
|
|
2031
1283
|
return !!foundRoutes.length;
|
|
2032
1284
|
};
|
|
2033
|
-
|
|
2034
1285
|
findMatchInRoutes([], filteredRoutes);
|
|
2035
|
-
|
|
2036
1286
|
if (!foundRoutes.length) {
|
|
2037
1287
|
return;
|
|
2038
1288
|
}
|
|
2039
|
-
|
|
2040
1289
|
foundRoutes.forEach(foundRoute => {
|
|
2041
|
-
var
|
|
2042
|
-
|
|
1290
|
+
var _store$matchCache$mat;
|
|
2043
1291
|
const interpolatedPath = interpolatePath(foundRoute.routePath, params);
|
|
2044
1292
|
const matchId = interpolatePath(foundRoute.routeId, params, true);
|
|
2045
|
-
const match = existingMatches.find(d => d.matchId === matchId) || ((
|
|
1293
|
+
const match = existingMatches.find(d => d.matchId === matchId) || ((_store$matchCache$mat = store.matchCache[matchId]) == null ? void 0 : _store$matchCache$mat.match) || createRouteMatch(router, foundRoute, {
|
|
1294
|
+
parentMatch,
|
|
2046
1295
|
matchId,
|
|
2047
1296
|
params,
|
|
2048
|
-
pathname: joinPaths([
|
|
1297
|
+
pathname: joinPaths([router.basepath, interpolatedPath])
|
|
2049
1298
|
});
|
|
2050
1299
|
matches.push(match);
|
|
2051
1300
|
});
|
|
2052
1301
|
const foundRoute = last(foundRoutes);
|
|
2053
|
-
|
|
2054
1302
|
if ((_foundRoute$childRout = foundRoute.childRoutes) != null && _foundRoute$childRout.length) {
|
|
2055
1303
|
recurse(foundRoute.childRoutes);
|
|
2056
1304
|
}
|
|
2057
1305
|
};
|
|
2058
|
-
|
|
2059
1306
|
recurse([router.routeTree]);
|
|
2060
|
-
|
|
1307
|
+
linkMatches(matches);
|
|
2061
1308
|
return matches;
|
|
2062
1309
|
},
|
|
2063
1310
|
loadMatches: async (resolvedMatches, loaderOpts) => {
|
|
2064
|
-
|
|
1311
|
+
resolvedMatches.forEach(async match => {
|
|
2065
1312
|
// Validate the match (loads search params etc)
|
|
2066
1313
|
match.__.validate();
|
|
1314
|
+
});
|
|
2067
1315
|
|
|
1316
|
+
// Check each match middleware to see if the route can be accessed
|
|
1317
|
+
await Promise.all(resolvedMatches.map(async match => {
|
|
1318
|
+
try {
|
|
1319
|
+
await (match.options.beforeLoad == null ? void 0 : match.options.beforeLoad({
|
|
1320
|
+
router: router,
|
|
1321
|
+
match
|
|
1322
|
+
}));
|
|
1323
|
+
} catch (err) {
|
|
1324
|
+
if (!(loaderOpts != null && loaderOpts.preload)) {
|
|
1325
|
+
match.options.onLoadError == null ? void 0 : match.options.onLoadError(err);
|
|
1326
|
+
}
|
|
1327
|
+
throw err;
|
|
1328
|
+
}
|
|
1329
|
+
}));
|
|
1330
|
+
const matchPromises = resolvedMatches.map(async match => {
|
|
1331
|
+
var _search$__data;
|
|
1332
|
+
const search = match.store.search;
|
|
1333
|
+
if ((_search$__data = search.__data) != null && _search$__data.matchId && search.__data.matchId !== match.matchId) {
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
2068
1336
|
match.load(loaderOpts);
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
// If requested, start the pending timers
|
|
2072
|
-
if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
|
|
2073
|
-
// This might be completion, error, or a pending state
|
|
2074
|
-
|
|
1337
|
+
if (match.store.status !== 'success' && match.__.loadPromise) {
|
|
1338
|
+
// Wait for the first sign of activity from the match
|
|
2075
1339
|
await match.__.loadPromise;
|
|
2076
1340
|
}
|
|
2077
1341
|
});
|
|
2078
|
-
router.notify();
|
|
2079
1342
|
await Promise.all(matchPromises);
|
|
2080
1343
|
},
|
|
2081
|
-
|
|
2082
|
-
|
|
1344
|
+
loadMatchData: async routeMatch => {
|
|
1345
|
+
if (isServer || !router.options.useServerData) {
|
|
1346
|
+
return (await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
|
|
1347
|
+
// parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
|
|
1348
|
+
params: routeMatch.params,
|
|
1349
|
+
search: routeMatch.store.routeSearch,
|
|
1350
|
+
signal: routeMatch.__.abortController.signal
|
|
1351
|
+
}))) || {};
|
|
1352
|
+
} else {
|
|
1353
|
+
const next = router.buildNext({
|
|
1354
|
+
to: '.',
|
|
1355
|
+
search: d => ({
|
|
1356
|
+
...(d ?? {}),
|
|
1357
|
+
__data: {
|
|
1358
|
+
matchId: routeMatch.matchId
|
|
1359
|
+
}
|
|
1360
|
+
})
|
|
1361
|
+
});
|
|
1362
|
+
|
|
1363
|
+
// Refresh:
|
|
1364
|
+
// '/dashboard'
|
|
1365
|
+
// '/dashboard/invoices/'
|
|
1366
|
+
// '/dashboard/invoices/123'
|
|
1367
|
+
|
|
1368
|
+
// New:
|
|
1369
|
+
// '/dashboard/invoices/456'
|
|
2083
1370
|
|
|
1371
|
+
// TODO: batch requests when possible
|
|
1372
|
+
|
|
1373
|
+
const res = await fetch(next.href, {
|
|
1374
|
+
method: 'GET'
|
|
1375
|
+
// signal: routeMatch.__.abortController.signal,
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
if (res.ok) {
|
|
1379
|
+
return res.json();
|
|
1380
|
+
}
|
|
1381
|
+
throw new Error('Failed to fetch match data');
|
|
1382
|
+
}
|
|
1383
|
+
},
|
|
1384
|
+
invalidateRoute: opts => {
|
|
2084
1385
|
const next = router.buildNext(opts);
|
|
2085
1386
|
const unloadedMatchIds = router.matchRoutes(next.pathname).map(d => d.matchId);
|
|
2086
|
-
[...
|
|
1387
|
+
[...store.currentMatches, ...(store.pendingMatches ?? [])].forEach(match => {
|
|
2087
1388
|
if (unloadedMatchIds.includes(match.matchId)) {
|
|
2088
1389
|
match.invalidate();
|
|
2089
1390
|
}
|
|
2090
1391
|
});
|
|
2091
1392
|
},
|
|
2092
|
-
reload: () =>
|
|
1393
|
+
reload: () => navigate({
|
|
2093
1394
|
fromCurrent: true,
|
|
2094
1395
|
replace: true,
|
|
2095
1396
|
search: true
|
|
@@ -2098,31 +1399,28 @@ function createRouter(userOptions) {
|
|
|
2098
1399
|
return resolvePath(router.basepath, from, cleanPath(path));
|
|
2099
1400
|
},
|
|
2100
1401
|
matchRoute: (location, opts) => {
|
|
2101
|
-
var _location$from;
|
|
2102
|
-
|
|
2103
1402
|
// const location = router.buildNext(opts)
|
|
2104
|
-
location = _extends({}, location, {
|
|
2105
|
-
to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
|
|
2106
|
-
});
|
|
2107
|
-
const next = router.buildNext(location);
|
|
2108
1403
|
|
|
1404
|
+
location = {
|
|
1405
|
+
...location,
|
|
1406
|
+
to: location.to ? router.resolvePath(location.from ?? '', location.to) : undefined
|
|
1407
|
+
};
|
|
1408
|
+
const next = router.buildNext(location);
|
|
2109
1409
|
if (opts != null && opts.pending) {
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
|
|
1410
|
+
if (!store.pendingLocation) {
|
|
2113
1411
|
return false;
|
|
2114
1412
|
}
|
|
2115
|
-
|
|
2116
|
-
|
|
1413
|
+
return !!matchPathname(router.basepath, store.pendingLocation.pathname, {
|
|
1414
|
+
...opts,
|
|
2117
1415
|
to: next.pathname
|
|
2118
|
-
})
|
|
1416
|
+
});
|
|
2119
1417
|
}
|
|
2120
|
-
|
|
2121
|
-
|
|
1418
|
+
return matchPathname(router.basepath, store.currentLocation.pathname, {
|
|
1419
|
+
...opts,
|
|
2122
1420
|
to: next.pathname
|
|
2123
|
-
})
|
|
1421
|
+
});
|
|
2124
1422
|
},
|
|
2125
|
-
navigate: async
|
|
1423
|
+
navigate: async _ref => {
|
|
2126
1424
|
let {
|
|
2127
1425
|
from,
|
|
2128
1426
|
to = '.',
|
|
@@ -2130,22 +1428,21 @@ function createRouter(userOptions) {
|
|
|
2130
1428
|
hash,
|
|
2131
1429
|
replace,
|
|
2132
1430
|
params
|
|
2133
|
-
} =
|
|
1431
|
+
} = _ref;
|
|
2134
1432
|
// If this link simply reloads the current route,
|
|
2135
1433
|
// make sure it has a new key so it will trigger a data refresh
|
|
1434
|
+
|
|
2136
1435
|
// If this `to` is a valid external URL, return
|
|
2137
1436
|
// null for LinkUtils
|
|
2138
1437
|
const toString = String(to);
|
|
2139
1438
|
const fromString = String(from);
|
|
2140
1439
|
let isExternal;
|
|
2141
|
-
|
|
2142
1440
|
try {
|
|
2143
|
-
new URL(
|
|
1441
|
+
new URL(`${toString}`);
|
|
2144
1442
|
isExternal = true;
|
|
2145
1443
|
} catch (e) {}
|
|
2146
|
-
|
|
2147
1444
|
invariant(!isExternal, 'Attempting to navigate to external url with router.navigate!');
|
|
2148
|
-
return
|
|
1445
|
+
return navigate({
|
|
2149
1446
|
from: fromString,
|
|
2150
1447
|
to: toString,
|
|
2151
1448
|
search,
|
|
@@ -2154,9 +1451,7 @@ function createRouter(userOptions) {
|
|
|
2154
1451
|
params
|
|
2155
1452
|
});
|
|
2156
1453
|
},
|
|
2157
|
-
buildLink:
|
|
2158
|
-
var _preload, _ref10;
|
|
2159
|
-
|
|
1454
|
+
buildLink: _ref2 => {
|
|
2160
1455
|
let {
|
|
2161
1456
|
from,
|
|
2162
1457
|
to = '.',
|
|
@@ -2171,20 +1466,20 @@ function createRouter(userOptions) {
|
|
|
2171
1466
|
preloadGcMaxAge: userPreloadGcMaxAge,
|
|
2172
1467
|
preloadDelay: userPreloadDelay,
|
|
2173
1468
|
disabled
|
|
2174
|
-
} =
|
|
2175
|
-
|
|
1469
|
+
} = _ref2;
|
|
2176
1470
|
// If this link simply reloads the current route,
|
|
2177
1471
|
// make sure it has a new key so it will trigger a data refresh
|
|
1472
|
+
|
|
2178
1473
|
// If this `to` is a valid external URL, return
|
|
2179
1474
|
// null for LinkUtils
|
|
1475
|
+
|
|
2180
1476
|
try {
|
|
2181
|
-
new URL(
|
|
1477
|
+
new URL(`${to}`);
|
|
2182
1478
|
return {
|
|
2183
1479
|
type: 'external',
|
|
2184
1480
|
href: to
|
|
2185
1481
|
};
|
|
2186
1482
|
} catch (e) {}
|
|
2187
|
-
|
|
2188
1483
|
const nextOpts = {
|
|
2189
1484
|
from,
|
|
2190
1485
|
to,
|
|
@@ -2194,70 +1489,72 @@ function createRouter(userOptions) {
|
|
|
2194
1489
|
replace
|
|
2195
1490
|
};
|
|
2196
1491
|
const next = router.buildNext(nextOpts);
|
|
2197
|
-
preload =
|
|
2198
|
-
const preloadDelay =
|
|
1492
|
+
preload = preload ?? router.options.defaultPreload;
|
|
1493
|
+
const preloadDelay = userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0;
|
|
2199
1494
|
|
|
2200
|
-
|
|
2201
|
-
const
|
|
1495
|
+
// Compare path/hash for matches
|
|
1496
|
+
const pathIsEqual = store.currentLocation.pathname === next.pathname;
|
|
1497
|
+
const currentPathSplit = store.currentLocation.pathname.split('/');
|
|
2202
1498
|
const nextPathSplit = next.pathname.split('/');
|
|
2203
1499
|
const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
|
|
2204
|
-
const hashIsEqual =
|
|
2205
|
-
|
|
1500
|
+
const hashIsEqual = store.currentLocation.hash === next.hash;
|
|
1501
|
+
// Combine the matches based on user options
|
|
2206
1502
|
const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
|
|
2207
|
-
const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true;
|
|
1503
|
+
const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true;
|
|
2208
1504
|
|
|
2209
|
-
|
|
1505
|
+
// The final "active" test
|
|
1506
|
+
const isActive = pathTest && hashTest;
|
|
2210
1507
|
|
|
1508
|
+
// The click handler
|
|
2211
1509
|
const handleClick = e => {
|
|
2212
1510
|
if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === '_self') && e.button === 0) {
|
|
2213
1511
|
e.preventDefault();
|
|
2214
|
-
|
|
2215
1512
|
if (pathIsEqual && !search && !hash) {
|
|
2216
1513
|
router.invalidateRoute(nextOpts);
|
|
2217
|
-
}
|
|
2218
|
-
|
|
1514
|
+
}
|
|
2219
1515
|
|
|
2220
|
-
|
|
1516
|
+
// All is well? Navigate!
|
|
1517
|
+
navigate(nextOpts);
|
|
2221
1518
|
}
|
|
2222
|
-
};
|
|
2223
|
-
|
|
1519
|
+
};
|
|
2224
1520
|
|
|
1521
|
+
// The click handler
|
|
2225
1522
|
const handleFocus = e => {
|
|
2226
1523
|
if (preload) {
|
|
2227
1524
|
router.preloadRoute(nextOpts, {
|
|
2228
1525
|
maxAge: userPreloadMaxAge,
|
|
2229
1526
|
gcMaxAge: userPreloadGcMaxAge
|
|
1527
|
+
}).catch(err => {
|
|
1528
|
+
console.log(err);
|
|
1529
|
+
console.warn('Error preloading route! ☝️');
|
|
2230
1530
|
});
|
|
2231
1531
|
}
|
|
2232
1532
|
};
|
|
2233
|
-
|
|
2234
1533
|
const handleEnter = e => {
|
|
2235
1534
|
const target = e.target || {};
|
|
2236
|
-
|
|
2237
1535
|
if (preload) {
|
|
2238
1536
|
if (target.preloadTimeout) {
|
|
2239
1537
|
return;
|
|
2240
1538
|
}
|
|
2241
|
-
|
|
2242
1539
|
target.preloadTimeout = setTimeout(() => {
|
|
2243
1540
|
target.preloadTimeout = null;
|
|
2244
1541
|
router.preloadRoute(nextOpts, {
|
|
2245
1542
|
maxAge: userPreloadMaxAge,
|
|
2246
1543
|
gcMaxAge: userPreloadGcMaxAge
|
|
1544
|
+
}).catch(err => {
|
|
1545
|
+
console.log(err);
|
|
1546
|
+
console.warn('Error preloading route! ☝️');
|
|
2247
1547
|
});
|
|
2248
1548
|
}, preloadDelay);
|
|
2249
1549
|
}
|
|
2250
1550
|
};
|
|
2251
|
-
|
|
2252
1551
|
const handleLeave = e => {
|
|
2253
1552
|
const target = e.target || {};
|
|
2254
|
-
|
|
2255
1553
|
if (target.preloadTimeout) {
|
|
2256
1554
|
clearTimeout(target.preloadTimeout);
|
|
2257
1555
|
target.preloadTimeout = null;
|
|
2258
1556
|
}
|
|
2259
1557
|
};
|
|
2260
|
-
|
|
2261
1558
|
return {
|
|
2262
1559
|
type: 'internal',
|
|
2263
1560
|
next,
|
|
@@ -2270,182 +1567,36 @@ function createRouter(userOptions) {
|
|
|
2270
1567
|
};
|
|
2271
1568
|
},
|
|
2272
1569
|
buildNext: opts => {
|
|
2273
|
-
const next =
|
|
2274
|
-
|
|
1570
|
+
const next = buildLocation(opts);
|
|
2275
1571
|
const matches = router.matchRoutes(next.pathname);
|
|
2276
|
-
|
|
2277
|
-
const
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
|
|
2281
|
-
}).flat().filter(Boolean);
|
|
2282
|
-
|
|
2283
|
-
const __postSearchFilters = matches.map(match => {
|
|
2284
|
-
var _match$options$postSe;
|
|
2285
|
-
|
|
2286
|
-
return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
|
|
2287
|
-
}).flat().filter(Boolean);
|
|
2288
|
-
|
|
2289
|
-
return router.__.buildLocation(_extends({}, opts, {
|
|
1572
|
+
const __preSearchFilters = matches.map(match => match.options.preSearchFilters ?? []).flat().filter(Boolean);
|
|
1573
|
+
const __postSearchFilters = matches.map(match => match.options.postSearchFilters ?? []).flat().filter(Boolean);
|
|
1574
|
+
return buildLocation({
|
|
1575
|
+
...opts,
|
|
2290
1576
|
__preSearchFilters,
|
|
2291
1577
|
__postSearchFilters
|
|
2292
|
-
})
|
|
2293
|
-
},
|
|
2294
|
-
__: {
|
|
2295
|
-
buildRouteTree: rootRouteConfig => {
|
|
2296
|
-
const recurseRoutes = (routeConfigs, parent) => {
|
|
2297
|
-
return routeConfigs.map(routeConfig => {
|
|
2298
|
-
const routeOptions = routeConfig.options;
|
|
2299
|
-
const route = createRoute(routeConfig, routeOptions, parent, router); // {
|
|
2300
|
-
// pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
|
|
2301
|
-
// pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
|
|
2302
|
-
// }
|
|
2303
|
-
|
|
2304
|
-
const existingRoute = router.routesById[route.routeId];
|
|
2305
|
-
|
|
2306
|
-
if (existingRoute) {
|
|
2307
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
2308
|
-
console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
|
|
2309
|
-
}
|
|
2310
|
-
|
|
2311
|
-
throw new Error();
|
|
2312
|
-
}
|
|
2313
|
-
router.routesById[route.routeId] = route;
|
|
2314
|
-
const children = routeConfig.children;
|
|
2315
|
-
route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
|
|
2316
|
-
return route;
|
|
2317
|
-
});
|
|
2318
|
-
};
|
|
2319
|
-
|
|
2320
|
-
const routes = recurseRoutes([rootRouteConfig]);
|
|
2321
|
-
return routes[0];
|
|
2322
|
-
},
|
|
2323
|
-
parseLocation: (location, previousLocation) => {
|
|
2324
|
-
var _location$hash$split$;
|
|
2325
|
-
|
|
2326
|
-
const parsedSearch = router.options.parseSearch(location.search);
|
|
2327
|
-
return {
|
|
2328
|
-
pathname: location.pathname,
|
|
2329
|
-
searchStr: location.search,
|
|
2330
|
-
search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
|
|
2331
|
-
hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
|
|
2332
|
-
href: "" + location.pathname + location.search + location.hash,
|
|
2333
|
-
state: location.state,
|
|
2334
|
-
key: location.key
|
|
2335
|
-
};
|
|
2336
|
-
},
|
|
2337
|
-
navigate: location => {
|
|
2338
|
-
const next = router.buildNext(location);
|
|
2339
|
-
return router.__.commitLocation(next, location.replace);
|
|
2340
|
-
},
|
|
2341
|
-
buildLocation: function buildLocation(dest) {
|
|
2342
|
-
var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
|
|
2343
|
-
|
|
2344
|
-
if (dest === void 0) {
|
|
2345
|
-
dest = {};
|
|
2346
|
-
}
|
|
2347
|
-
|
|
2348
|
-
// const resolvedFrom: Location = {
|
|
2349
|
-
// ...router.location,
|
|
2350
|
-
const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
|
|
2351
|
-
|
|
2352
|
-
let pathname = resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
|
|
2353
|
-
|
|
2354
|
-
const fromMatches = router.matchRoutes(router.location.pathname, {
|
|
2355
|
-
strictParseParams: true
|
|
2356
|
-
});
|
|
2357
|
-
const toMatches = router.matchRoutes(pathname);
|
|
2358
|
-
|
|
2359
|
-
const prevParams = _extends({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
|
|
2360
|
-
|
|
2361
|
-
let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
2362
|
-
|
|
2363
|
-
if (nextParams) {
|
|
2364
|
-
toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
2365
|
-
Object.assign({}, nextParams, fn(nextParams));
|
|
2366
|
-
});
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
|
|
2370
|
-
|
|
2371
|
-
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
|
|
2372
|
-
|
|
2373
|
-
const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
|
|
2374
|
-
: dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
|
|
2375
|
-
: (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
|
|
2376
|
-
: {}; // Then post filters
|
|
2377
|
-
|
|
2378
|
-
const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
2379
|
-
const search = replaceEqualDeep(router.location.search, postFilteredSearch);
|
|
2380
|
-
const searchStr = router.options.stringifySearch(search);
|
|
2381
|
-
let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
|
|
2382
|
-
hash = hash ? "#" + hash : '';
|
|
2383
|
-
return {
|
|
2384
|
-
pathname,
|
|
2385
|
-
search,
|
|
2386
|
-
searchStr,
|
|
2387
|
-
state: router.location.state,
|
|
2388
|
-
hash,
|
|
2389
|
-
href: "" + pathname + searchStr + hash,
|
|
2390
|
-
key: dest.key
|
|
2391
|
-
};
|
|
2392
|
-
},
|
|
2393
|
-
commitLocation: (next, replace) => {
|
|
2394
|
-
const id = '' + Date.now() + Math.random();
|
|
2395
|
-
if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
|
|
2396
|
-
let nextAction = 'replace';
|
|
2397
|
-
|
|
2398
|
-
if (!replace) {
|
|
2399
|
-
nextAction = 'push';
|
|
2400
|
-
}
|
|
2401
|
-
|
|
2402
|
-
const isSameUrl = router.__.parseLocation(history.location).href === next.href;
|
|
2403
|
-
|
|
2404
|
-
if (isSameUrl && !next.key) {
|
|
2405
|
-
nextAction = 'replace';
|
|
2406
|
-
}
|
|
2407
|
-
|
|
2408
|
-
if (nextAction === 'replace') {
|
|
2409
|
-
history.replace({
|
|
2410
|
-
pathname: next.pathname,
|
|
2411
|
-
hash: next.hash,
|
|
2412
|
-
search: next.searchStr
|
|
2413
|
-
}, {
|
|
2414
|
-
id
|
|
2415
|
-
});
|
|
2416
|
-
} else {
|
|
2417
|
-
history.push({
|
|
2418
|
-
pathname: next.pathname,
|
|
2419
|
-
hash: next.hash,
|
|
2420
|
-
search: next.searchStr
|
|
2421
|
-
}, {
|
|
2422
|
-
id
|
|
2423
|
-
});
|
|
2424
|
-
}
|
|
2425
|
-
|
|
2426
|
-
router.navigationPromise = new Promise(resolve => {
|
|
2427
|
-
const previousNavigationResolve = router.resolveNavigation;
|
|
2428
|
-
|
|
2429
|
-
router.resolveNavigation = () => {
|
|
2430
|
-
previousNavigationResolve();
|
|
2431
|
-
resolve();
|
|
2432
|
-
};
|
|
2433
|
-
});
|
|
2434
|
-
return router.navigationPromise;
|
|
2435
|
-
}
|
|
1578
|
+
});
|
|
2436
1579
|
}
|
|
2437
1580
|
};
|
|
2438
|
-
router.
|
|
2439
|
-
router.state.location = router.location;
|
|
2440
|
-
router.update(userOptions); // Allow frameworks to hook into the router creation
|
|
1581
|
+
router.update(userOptions);
|
|
2441
1582
|
|
|
1583
|
+
// Allow frameworks to hook into the router creation
|
|
2442
1584
|
router.options.createRouter == null ? void 0 : router.options.createRouter(router);
|
|
2443
1585
|
return router;
|
|
2444
1586
|
}
|
|
2445
|
-
|
|
2446
1587
|
function isCtrlEvent(e) {
|
|
2447
1588
|
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
2448
1589
|
}
|
|
1590
|
+
function linkMatches(matches) {
|
|
1591
|
+
matches.forEach((match, index) => {
|
|
1592
|
+
const parent = matches[index - 1];
|
|
1593
|
+
if (parent) {
|
|
1594
|
+
match.__.setParentMatch(parent);
|
|
1595
|
+
} else {
|
|
1596
|
+
match.__.setParentMatch(undefined);
|
|
1597
|
+
}
|
|
1598
|
+
});
|
|
1599
|
+
}
|
|
2449
1600
|
|
|
2450
|
-
export {
|
|
1601
|
+
export { cleanPath, createRoute, createRouteConfig, createRouteMatch, createRouter, decode, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, interpolatePath, joinPaths, last, matchByPath, matchPathname, parsePathname, parseSearchWith, pick, resolvePath, rootRouteId, sharedClone, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, warning };
|
|
2451
1602
|
//# sourceMappingURL=index.js.map
|