@tanstack/router-core 0.0.1-alpha.9 → 0.0.1-beta.10

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.
@@ -23,9 +23,22 @@ var utils = require('./utils.js');
23
23
 
24
24
  var _window$document;
25
25
  // Detect if we're in the DOM
26
- const isServer = Boolean(typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement)); // This is the default history object if none is defined
27
-
28
- const createDefaultHistory = () => !isServer ? index.createBrowserHistory() : index.createMemoryHistory();
26
+ const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement); // This is the default history object if none is defined
27
+
28
+ const createDefaultHistory = () => isServer ? index.createMemoryHistory() : index.createBrowserHistory();
29
+
30
+ function getInitialRouterState() {
31
+ return {
32
+ status: 'idle',
33
+ location: null,
34
+ matches: [],
35
+ actions: {},
36
+ loaders: {},
37
+ lastUpdated: Date.now(),
38
+ isFetching: false,
39
+ isPreloading: false
40
+ };
41
+ }
29
42
 
30
43
  function createRouter(userOptions) {
31
44
  var _userOptions$stringif, _userOptions$parseSea;
@@ -43,9 +56,9 @@ function createRouter(userOptions) {
43
56
  });
44
57
 
45
58
  let router = {
59
+ history,
46
60
  options: originalOptions,
47
61
  listeners: [],
48
- removeActionQueue: [],
49
62
  // Resolved after construction
50
63
  basepath: '',
51
64
  routeTree: undefined,
@@ -56,15 +69,10 @@ function createRouter(userOptions) {
56
69
  navigationPromise: Promise.resolve(),
57
70
  resolveNavigation: () => {},
58
71
  matchCache: {},
59
- state: {
60
- status: 'idle',
61
- location: null,
62
- matches: [],
63
- actions: {},
64
- loaderData: {},
65
- lastUpdated: Date.now(),
66
- isFetching: false,
67
- isPreloading: false
72
+ state: getInitialRouterState(),
73
+ reset: () => {
74
+ router.state = getInitialRouterState();
75
+ router.notify();
68
76
  },
69
77
  startedLoadingAt: Date.now(),
70
78
  subscribe: listener => {
@@ -81,25 +89,45 @@ function createRouter(userOptions) {
81
89
  isFetching: router.state.status === 'loading' || router.state.matches.some(d => d.isFetching),
82
90
  isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
83
91
  });
84
- route.cascadeLoaderData(router.state.matches);
85
- router.listeners.forEach(listener => listener());
92
+ cascadeLoaderData(router.state.matches);
93
+ router.listeners.forEach(listener => listener(router));
94
+ },
95
+ dehydrateState: () => {
96
+ return _rollupPluginBabelHelpers["extends"]({}, utils.pick(router.state, ['status', 'location', 'lastUpdated']), {
97
+ matches: router.state.matches.map(match => utils.pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
98
+ });
99
+ },
100
+ hydrateState: dehydratedState => {
101
+ // Match the routes
102
+ const matches = router.matchRoutes(router.location.pathname, {
103
+ strictParseParams: true
104
+ });
105
+ matches.forEach((match, index) => {
106
+ const dehydratedMatch = dehydratedState.matches[index];
107
+ tinyInvariant["default"](dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
108
+ Object.assign(match, dehydratedMatch);
109
+ });
110
+ router.loadMatches(matches);
111
+ router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, dehydratedState, {
112
+ matches
113
+ });
86
114
  },
87
115
  mount: () => {
88
- const next = router.buildLocation({
116
+ const next = router.__.buildLocation({
89
117
  to: '.',
90
118
  search: true,
91
119
  hash: true
92
120
  }); // If the current location isn't updated, trigger a navigation
93
121
  // to the current location. Otherwise, load the current location.
94
122
 
123
+
95
124
  if (next.href !== router.location.href) {
96
- router.commitLocation(next, true);
97
- } else {
98
- router.loadLocation();
99
- }
125
+ router.__.commitLocation(next, true);
126
+ } // router.load()
127
+
100
128
 
101
- const unsub = history.listen(event => {
102
- router.loadLocation(router.parseLocation(event.location, router.location));
129
+ const unsub = router.history.listen(event => {
130
+ router.load(router.__.parseLocation(event.location, router.location));
103
131
  }); // addEventListener does not exist in React Native, but window does
104
132
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
105
133
 
@@ -110,16 +138,30 @@ function createRouter(userOptions) {
110
138
  }
111
139
 
112
140
  return () => {
113
- unsub(); // Be sure to unsubscribe if a new handler is set
141
+ unsub();
114
142
 
115
- window.removeEventListener('visibilitychange', router.onFocus);
116
- window.removeEventListener('focus', router.onFocus);
143
+ if (!isServer && window.removeEventListener) {
144
+ // Be sure to unsubscribe if a new handler is set
145
+ window.removeEventListener('visibilitychange', router.onFocus);
146
+ window.removeEventListener('focus', router.onFocus);
147
+ }
117
148
  };
118
149
  },
119
150
  onFocus: () => {
120
- router.loadLocation();
151
+ router.load();
121
152
  },
122
153
  update: opts => {
154
+ const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
155
+
156
+ if (!router.location || newHistory) {
157
+ if (opts != null && opts.history) {
158
+ router.history = opts.history;
159
+ }
160
+
161
+ router.location = router.__.parseLocation(router.history.location);
162
+ router.state.location = router.location;
163
+ }
164
+
123
165
  Object.assign(router.options, opts);
124
166
  const {
125
167
  basepath,
@@ -129,204 +171,30 @@ function createRouter(userOptions) {
129
171
 
130
172
  if (routeConfig) {
131
173
  router.routesById = {};
132
- router.routeTree = router.buildRouteTree(routeConfig);
174
+ router.routeTree = router.__.buildRouteTree(routeConfig);
133
175
  }
134
176
 
135
177
  return router;
136
178
  },
137
- buildRouteTree: rootRouteConfig => {
138
- const recurseRoutes = (routeConfigs, parent) => {
139
- return routeConfigs.map(routeConfig => {
140
- const routeOptions = routeConfig.options;
141
- const route$1 = route.createRoute(routeConfig, routeOptions, parent, router); // {
142
- // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
143
- // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
144
- // }
145
-
146
- const existingRoute = router.routesById[route$1.routeId];
147
-
148
- if (existingRoute) {
149
- if (process.env.NODE_ENV !== 'production') {
150
- console.warn("Duplicate routes found with id: " + String(route$1.routeId), router.routesById, route$1);
151
- }
152
-
153
- throw new Error();
154
- }
155
- router.routesById[route$1.routeId] = route$1;
156
- const children = routeConfig.children;
157
- route$1.childRoutes = children != null && children.length ? recurseRoutes(children, route$1) : undefined;
158
- return route$1;
159
- });
160
- };
161
-
162
- const routes = recurseRoutes([rootRouteConfig]);
163
- return routes[0];
164
- },
165
- parseLocation: (location, previousLocation) => {
166
- var _location$hash$split$;
167
-
168
- const parsedSearch = router.options.parseSearch(location.search);
169
- return {
170
- pathname: location.pathname,
171
- searchStr: location.search,
172
- search: utils.replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
173
- hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
174
- href: "" + location.pathname + location.search + location.hash,
175
- state: location.state,
176
- key: location.key
177
- };
178
- },
179
- buildLocation: function buildLocation(dest) {
180
- var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
181
-
182
- if (dest === void 0) {
183
- dest = {};
184
- }
185
-
186
- // const resolvedFrom: Location = {
187
- // ...router.location,
188
- const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
189
-
190
- let pathname = path.resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
191
-
192
- const fromMatches = router.matchRoutes(router.location.pathname, {
193
- strictParseParams: true
194
- });
195
- const toMatches = router.matchRoutes(pathname);
196
-
197
- const prevParams = _rollupPluginBabelHelpers["extends"]({}, (_last = utils.last(fromMatches)) == null ? void 0 : _last.params);
198
-
199
- let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : utils.functionalUpdate(dest.params, prevParams);
200
-
201
- if (nextParams) {
202
- toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
203
- Object.assign({}, nextParams, fn(nextParams));
204
- });
205
- }
206
-
207
- pathname = path.interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
208
-
209
- 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
210
-
211
- const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
212
- : dest.search ? (_functionalUpdate = utils.functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
213
- : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
214
- : {}; // Then post filters
215
-
216
- const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
217
- const search = utils.replaceEqualDeep(router.location.search, postFilteredSearch);
218
- const searchStr = router.options.stringifySearch(search);
219
- let hash = dest.hash === true ? router.location.hash : utils.functionalUpdate(dest.hash, router.location.hash);
220
- hash = hash ? "#" + hash : '';
221
- return {
222
- pathname,
223
- search,
224
- searchStr,
225
- state: router.location.state,
226
- hash,
227
- href: "" + pathname + searchStr + hash,
228
- key: dest.key
229
- };
230
- },
231
- commitLocation: (next, replace) => {
232
- const id = '' + Date.now() + Math.random();
233
- if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
234
- let nextAction = 'replace';
235
-
236
- if (!replace) {
237
- nextAction = 'push';
238
- }
239
-
240
- const isSameUrl = router.parseLocation(history.location).href === next.href;
241
-
242
- if (isSameUrl && !next.key) {
243
- nextAction = 'replace';
244
- }
245
-
246
- if (nextAction === 'replace') {
247
- history.replace({
248
- pathname: next.pathname,
249
- hash: next.hash,
250
- search: next.searchStr
251
- }, {
252
- id
253
- });
254
- } else {
255
- history.push({
256
- pathname: next.pathname,
257
- hash: next.hash,
258
- search: next.searchStr
259
- }, {
260
- id
261
- });
262
- }
263
-
264
- router.navigationPromise = new Promise(resolve => {
265
- const previousNavigationResolve = router.resolveNavigation;
266
-
267
- router.resolveNavigation = () => {
268
- previousNavigationResolve();
269
- resolve();
270
- };
271
- });
272
- return router.navigationPromise;
273
- },
274
- buildNext: opts => {
275
- const next = router.buildLocation(opts);
276
- const matches = router.matchRoutes(next.pathname);
277
-
278
- const __preSearchFilters = matches.map(match => {
279
- var _match$options$preSea;
280
-
281
- return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
282
- }).flat().filter(Boolean);
283
-
284
- const __postSearchFilters = matches.map(match => {
285
- var _match$options$postSe;
286
-
287
- return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
288
- }).flat().filter(Boolean);
289
-
290
- return router.buildLocation(_rollupPluginBabelHelpers["extends"]({}, opts, {
291
- __preSearchFilters,
292
- __postSearchFilters
293
- }));
294
- },
295
179
  cancelMatches: () => {
296
180
  var _router$state$pending, _router$state$pending2;
297
181
  [...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 => {
298
182
  match.cancel();
299
183
  });
300
184
  },
301
- loadLocation: async next => {
185
+ load: async next => {
302
186
  const id = Math.random();
303
187
  router.startedLoadingAt = id;
304
188
 
305
189
  if (next) {
306
190
  // Ingest the new location
307
191
  router.location = next;
308
- } // Clear out old actions
192
+ } // Cancel any pending matches
309
193
 
310
194
 
311
- router.removeActionQueue.forEach(_ref => {
312
- let {
313
- action,
314
- actionState
315
- } = _ref;
316
-
317
- if (router.state.currentAction === actionState) {
318
- router.state.currentAction = undefined;
319
- }
320
-
321
- if (action.current === actionState) {
322
- action.current = undefined;
323
- }
324
- });
325
- router.removeActionQueue = []; // Cancel any pending matches
326
-
327
195
  router.cancelMatches(); // Match the routes
328
196
 
329
- const matches = router.matchRoutes(location.pathname, {
197
+ const matches = router.matchRoutes(router.location.pathname, {
330
198
  strictParseParams: true
331
199
  });
332
200
  router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
@@ -359,19 +227,24 @@ function createRouter(userOptions) {
359
227
  });
360
228
  const now = Date.now();
361
229
  exiting.forEach(d => {
362
- var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
230
+ var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
363
231
 
364
232
  d.__.onExit == null ? void 0 : d.__.onExit({
365
233
  params: d.params,
366
234
  search: d.routeSearch
367
- }); // Clear idle error states when match leaves
235
+ }); // // Clear actions
236
+ // if (d.action) {
237
+ // d.action.current = undefined
238
+ // d.action.submissions = []
239
+ // }
240
+ // Clear idle error states when match leaves
368
241
 
369
242
  if (d.status === 'error' && !d.isFetching) {
370
243
  d.status = 'idle';
371
244
  d.error = undefined;
372
245
  }
373
246
 
374
- 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);
247
+ const gc = Math.max((_ref = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref : 0, (_ref2 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref2 : 0);
375
248
 
376
249
  if (gc > 0) {
377
250
  router.matchCache[d.matchId] = {
@@ -394,18 +267,21 @@ function createRouter(userOptions) {
394
267
  params: d.params,
395
268
  search: d.search
396
269
  });
397
- });
398
-
399
- if (matches.some(d => d.status === 'loading')) {
400
- router.notify();
401
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
402
- }
270
+ delete router.matchCache[d.matchId];
271
+ }); // router.notify()
403
272
 
404
273
  if (router.startedLoadingAt !== id) {
405
274
  // Ignore side-effects of match loading
406
275
  return;
407
276
  }
408
277
 
278
+ matches.forEach(match => {
279
+ // Clear actions
280
+ if (match.action) {
281
+ match.action.current = undefined;
282
+ match.action.submissions = [];
283
+ }
284
+ });
409
285
  router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
410
286
  location: router.location,
411
287
  matches,
@@ -446,7 +322,7 @@ function createRouter(userOptions) {
446
322
  return matches;
447
323
  },
448
324
  preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
449
- var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
325
+ var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
450
326
 
451
327
  if (navigateOpts === void 0) {
452
328
  navigateOpts = router.location;
@@ -458,8 +334,8 @@ function createRouter(userOptions) {
458
334
  });
459
335
  await router.loadMatches(matches, {
460
336
  preload: true,
461
- maxAge: (_ref4 = (_ref5 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref5 : router.options.defaultLoaderMaxAge) != null ? _ref4 : 0,
462
- gcMaxAge: (_ref6 = (_ref7 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0
337
+ maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
338
+ gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
463
339
  });
464
340
  return matches;
465
341
  },
@@ -549,42 +425,24 @@ function createRouter(userOptions) {
549
425
  };
550
426
 
551
427
  recurse([router.routeTree]);
552
- route.cascadeLoaderData(matches);
428
+ cascadeLoaderData(matches);
553
429
  return matches;
554
430
  },
555
431
  loadMatches: async (resolvedMatches, loaderOpts) => {
556
- const now = Date.now();
557
- const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0;
558
432
  const matchPromises = resolvedMatches.map(async match => {
559
433
  // Validate the match (loads search params etc)
560
- match.__.validate(); // If this is a preload, add it to the preload cache
561
-
562
-
563
- if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
564
- // If the match is currently active, don't preload it
565
- if (router.state.matches.find(d => d.matchId === match.matchId)) {
566
- return;
567
- }
434
+ match.__.validate();
568
435
 
569
- router.matchCache[match.matchId] = {
570
- gc: now + loaderOpts.gcMaxAge,
571
- match
572
- };
573
- } // If the match is invalid, errored or idle, trigger it to load
574
-
575
-
576
- if (match.status === 'success' && match.getIsInvalid() || match.status === 'error' || match.status === 'idle') {
577
- const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
578
- match.load({
579
- maxAge
580
- });
581
- }
436
+ match.load(loaderOpts);
582
437
 
583
438
  if (match.status === 'loading') {
584
439
  // If requested, start the pending timers
585
- if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
586
- // This might be completion, error, or a pending state
440
+ if (loaderOpts != null && loaderOpts.withPending) match.__.startPending();
441
+ }
587
442
 
443
+ if (match.__.loadPromise) {
444
+ // Wait for the first sign of activity from the match
445
+ // This might be completion, error, or a pending state
588
446
  await match.__.loadPromise;
589
447
  }
590
448
  });
@@ -602,7 +460,7 @@ function createRouter(userOptions) {
602
460
  }
603
461
  });
604
462
  },
605
- reload: () => router._navigate({
463
+ reload: () => router.__.navigate({
606
464
  fromCurrent: true,
607
465
  replace: true,
608
466
  search: true
@@ -635,11 +493,7 @@ function createRouter(userOptions) {
635
493
  to: next.pathname
636
494
  }));
637
495
  },
638
- _navigate: location => {
639
- const next = router.buildNext(location);
640
- return router.commitLocation(next, location.replace);
641
- },
642
- navigate: async _ref8 => {
496
+ navigate: async _ref7 => {
643
497
  let {
644
498
  from,
645
499
  to = '.',
@@ -647,7 +501,7 @@ function createRouter(userOptions) {
647
501
  hash,
648
502
  replace,
649
503
  params
650
- } = _ref8;
504
+ } = _ref7;
651
505
  // If this link simply reloads the current route,
652
506
  // make sure it has a new key so it will trigger a data refresh
653
507
  // If this `to` is a valid external URL, return
@@ -662,7 +516,7 @@ function createRouter(userOptions) {
662
516
  } catch (e) {}
663
517
 
664
518
  tinyInvariant["default"](!isExternal, 'Attempting to navigate to external url with router.navigate!');
665
- return router._navigate({
519
+ return router.__.navigate({
666
520
  from: fromString,
667
521
  to: toString,
668
522
  search,
@@ -671,8 +525,8 @@ function createRouter(userOptions) {
671
525
  params
672
526
  });
673
527
  },
674
- buildLink: _ref9 => {
675
- var _preload, _ref10;
528
+ buildLink: _ref8 => {
529
+ var _preload, _ref9;
676
530
 
677
531
  let {
678
532
  from,
@@ -688,7 +542,7 @@ function createRouter(userOptions) {
688
542
  preloadGcMaxAge: userPreloadGcMaxAge,
689
543
  preloadDelay: userPreloadDelay,
690
544
  disabled
691
- } = _ref9;
545
+ } = _ref8;
692
546
 
693
547
  // If this link simply reloads the current route,
694
548
  // make sure it has a new key so it will trigger a data refresh
@@ -712,7 +566,7 @@ function createRouter(userOptions) {
712
566
  };
713
567
  const next = router.buildNext(nextOpts);
714
568
  preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
715
- const preloadDelay = (_ref10 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref10 : 0; // Compare path/hash for matches
569
+ const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
716
570
 
717
571
  const pathIsEqual = router.state.location.pathname === next.pathname;
718
572
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -734,7 +588,7 @@ function createRouter(userOptions) {
734
588
  } // All is well? Navigate!)
735
589
 
736
590
 
737
- router._navigate(nextOpts);
591
+ router.__.navigate(nextOpts);
738
592
  }
739
593
  }; // The click handler
740
594
 
@@ -785,10 +639,169 @@ function createRouter(userOptions) {
785
639
  isActive,
786
640
  disabled
787
641
  };
642
+ },
643
+ buildNext: opts => {
644
+ const next = router.__.buildLocation(opts);
645
+
646
+ const matches = router.matchRoutes(next.pathname);
647
+
648
+ const __preSearchFilters = matches.map(match => {
649
+ var _match$options$preSea;
650
+
651
+ return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
652
+ }).flat().filter(Boolean);
653
+
654
+ const __postSearchFilters = matches.map(match => {
655
+ var _match$options$postSe;
656
+
657
+ return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
658
+ }).flat().filter(Boolean);
659
+
660
+ return router.__.buildLocation(_rollupPluginBabelHelpers["extends"]({}, opts, {
661
+ __preSearchFilters,
662
+ __postSearchFilters
663
+ }));
664
+ },
665
+ __: {
666
+ buildRouteTree: rootRouteConfig => {
667
+ const recurseRoutes = (routeConfigs, parent) => {
668
+ return routeConfigs.map(routeConfig => {
669
+ const routeOptions = routeConfig.options;
670
+ const route$1 = route.createRoute(routeConfig, routeOptions, parent, router);
671
+ const existingRoute = router.routesById[route$1.routeId];
672
+
673
+ if (existingRoute) {
674
+ if (process.env.NODE_ENV !== 'production') {
675
+ console.warn("Duplicate routes found with id: " + String(route$1.routeId), router.routesById, route$1);
676
+ }
677
+
678
+ throw new Error();
679
+ }
680
+ router.routesById[route$1.routeId] = route$1;
681
+ const children = routeConfig.children;
682
+ route$1.childRoutes = children != null && children.length ? recurseRoutes(children, route$1) : undefined;
683
+ return route$1;
684
+ });
685
+ };
686
+
687
+ const routes = recurseRoutes([rootRouteConfig]);
688
+ return routes[0];
689
+ },
690
+ parseLocation: (location, previousLocation) => {
691
+ var _location$hash$split$;
692
+
693
+ const parsedSearch = router.options.parseSearch(location.search);
694
+ return {
695
+ pathname: location.pathname,
696
+ searchStr: location.search,
697
+ search: utils.replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
698
+ hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
699
+ href: "" + location.pathname + location.search + location.hash,
700
+ state: location.state,
701
+ key: location.key
702
+ };
703
+ },
704
+ navigate: location => {
705
+ const next = router.buildNext(location);
706
+ return router.__.commitLocation(next, location.replace);
707
+ },
708
+ buildLocation: function buildLocation(dest) {
709
+ var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
710
+
711
+ if (dest === void 0) {
712
+ dest = {};
713
+ }
714
+
715
+ // const resolvedFrom: Location = {
716
+ // ...router.location,
717
+ const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
718
+
719
+ let pathname = path.resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
720
+
721
+ const fromMatches = router.matchRoutes(router.location.pathname, {
722
+ strictParseParams: true
723
+ });
724
+ const toMatches = router.matchRoutes(pathname);
725
+
726
+ const prevParams = _rollupPluginBabelHelpers["extends"]({}, (_last = utils.last(fromMatches)) == null ? void 0 : _last.params);
727
+
728
+ let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : utils.functionalUpdate(dest.params, prevParams);
729
+
730
+ if (nextParams) {
731
+ toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
732
+ Object.assign({}, nextParams, fn(nextParams));
733
+ });
734
+ }
735
+
736
+ pathname = path.interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
737
+
738
+ 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
739
+
740
+ const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
741
+ : dest.search ? (_functionalUpdate = utils.functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
742
+ : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
743
+ : {}; // Then post filters
744
+
745
+ const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
746
+ const search = utils.replaceEqualDeep(router.location.search, postFilteredSearch);
747
+ const searchStr = router.options.stringifySearch(search);
748
+ let hash = dest.hash === true ? router.location.hash : utils.functionalUpdate(dest.hash, router.location.hash);
749
+ hash = hash ? "#" + hash : '';
750
+ return {
751
+ pathname,
752
+ search,
753
+ searchStr,
754
+ state: router.location.state,
755
+ hash,
756
+ href: "" + pathname + searchStr + hash,
757
+ key: dest.key
758
+ };
759
+ },
760
+ commitLocation: (next, replace) => {
761
+ const id = '' + Date.now() + Math.random();
762
+ if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
763
+ let nextAction = 'replace';
764
+
765
+ if (!replace) {
766
+ nextAction = 'push';
767
+ }
768
+
769
+ const isSameUrl = router.__.parseLocation(history.location).href === next.href;
770
+
771
+ if (isSameUrl && !next.key) {
772
+ nextAction = 'replace';
773
+ }
774
+
775
+ if (nextAction === 'replace') {
776
+ history.replace({
777
+ pathname: next.pathname,
778
+ hash: next.hash,
779
+ search: next.searchStr
780
+ }, {
781
+ id
782
+ });
783
+ } else {
784
+ history.push({
785
+ pathname: next.pathname,
786
+ hash: next.hash,
787
+ search: next.searchStr
788
+ }, {
789
+ id
790
+ });
791
+ }
792
+
793
+ router.navigationPromise = new Promise(resolve => {
794
+ const previousNavigationResolve = router.resolveNavigation;
795
+
796
+ router.resolveNavigation = () => {
797
+ previousNavigationResolve();
798
+ resolve();
799
+ };
800
+ });
801
+ return router.navigationPromise;
802
+ }
788
803
  }
789
804
  };
790
- router.location = router.parseLocation(history.location);
791
- router.state.location = router.location;
792
805
  router.update(userOptions); // Allow frameworks to hook into the router creation
793
806
 
794
807
  router.options.createRouter == null ? void 0 : router.options.createRouter(router);
@@ -799,5 +812,15 @@ function isCtrlEvent(e) {
799
812
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
800
813
  }
801
814
 
815
+ function cascadeLoaderData(matches) {
816
+ matches.forEach((match, index) => {
817
+ const parent = matches[index - 1];
818
+
819
+ if (parent) {
820
+ match.loaderData = utils.replaceEqualDeep(match.loaderData, _rollupPluginBabelHelpers["extends"]({}, parent.loaderData, match.routeLoaderData));
821
+ }
822
+ });
823
+ }
824
+
802
825
  exports.createRouter = createRouter;
803
826
  //# sourceMappingURL=router.js.map