@tanstack/router-core 0.0.1-beta.4 → 0.0.1-beta.41

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