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