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