@tanstack/router-core 0.0.1-beta.35 → 0.0.1-beta.39

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 (38) hide show
  1. package/build/cjs/index.js +2 -1
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/cjs/path.js +5 -7
  4. package/build/cjs/path.js.map +1 -1
  5. package/build/cjs/route.js +112 -96
  6. package/build/cjs/route.js.map +1 -1
  7. package/build/cjs/routeConfig.js +2 -2
  8. package/build/cjs/routeConfig.js.map +1 -1
  9. package/build/cjs/routeMatch.js +107 -65
  10. package/build/cjs/routeMatch.js.map +1 -1
  11. package/build/cjs/router.js +352 -372
  12. package/build/cjs/router.js.map +1 -1
  13. package/build/cjs/searchParams.js +4 -3
  14. package/build/cjs/searchParams.js.map +1 -1
  15. package/build/cjs/sharedClone.js +122 -0
  16. package/build/cjs/sharedClone.js.map +1 -0
  17. package/build/cjs/utils.js +1 -59
  18. package/build/cjs/utils.js.map +1 -1
  19. package/build/esm/index.js +686 -614
  20. package/build/esm/index.js.map +1 -1
  21. package/build/stats-html.html +1 -1
  22. package/build/stats-react.json +183 -158
  23. package/build/types/index.d.ts +61 -78
  24. package/build/umd/index.development.js +1032 -617
  25. package/build/umd/index.development.js.map +1 -1
  26. package/build/umd/index.production.js +1 -1
  27. package/build/umd/index.production.js.map +1 -1
  28. package/package.json +2 -1
  29. package/src/index.ts +1 -0
  30. package/src/link.ts +20 -12
  31. package/src/route.ts +160 -140
  32. package/src/routeConfig.ts +7 -2
  33. package/src/routeMatch.ts +146 -99
  34. package/src/router.ts +462 -523
  35. package/src/sharedClone.ts +118 -0
  36. package/src/utils.ts +0 -65
  37. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -31
  38. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
@@ -12,14 +12,15 @@
12
12
 
13
13
  Object.defineProperty(exports, '__esModule', { value: true });
14
14
 
15
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
16
15
  var history = require('history');
17
16
  var invariant = require('tiny-invariant');
18
17
  var path = require('./path.js');
19
18
  var route = require('./route.js');
20
19
  var routeMatch = require('./routeMatch.js');
21
20
  var searchParams = require('./searchParams.js');
21
+ var reactivity = require('@solidjs/reactivity');
22
22
  var utils = require('./utils.js');
23
+ var sharedClone = require('./sharedClone.js');
23
24
 
24
25
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
25
26
 
@@ -34,216 +35,296 @@ const createDefaultHistory = () => isServer ? history.createMemoryHistory() : hi
34
35
  function getInitialRouterState() {
35
36
  return {
36
37
  status: 'idle',
37
- location: null,
38
- matches: [],
38
+ latestLocation: null,
39
+ currentLocation: null,
40
+ currentMatches: [],
39
41
  actions: {},
40
42
  loaders: {},
41
43
  lastUpdated: Date.now(),
42
- isFetching: false,
43
- isPreloading: false
44
+ matchCache: {},
45
+ get isFetching() {
46
+ return this.status === 'loading' || this.currentMatches.some(d => d.store.isFetching);
47
+ },
48
+ get isPreloading() {
49
+ return Object.values(this.matchCache).some(d => d.match.store.isFetching && !this.currentMatches.find(dd => dd.matchId === d.match.matchId));
50
+ }
44
51
  };
45
52
  }
46
53
  function createRouter(userOptions) {
47
- var _userOptions$stringif, _userOptions$parseSea;
48
- const history = (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory();
49
- const originalOptions = _rollupPluginBabelHelpers["extends"]({
54
+ const originalOptions = {
50
55
  defaultLoaderGcMaxAge: 5 * 60 * 1000,
51
56
  defaultLoaderMaxAge: 0,
52
57
  defaultPreloadMaxAge: 2000,
53
58
  defaultPreloadDelay: 50,
54
- context: undefined
55
- }, userOptions, {
56
- stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : searchParams.defaultStringifySearch,
57
- parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : searchParams.defaultParseSearch
58
- });
59
- let router = {
59
+ context: undefined,
60
+ ...userOptions,
61
+ stringifySearch: (userOptions == null ? void 0 : userOptions.stringifySearch) ?? searchParams.defaultStringifySearch,
62
+ parseSearch: (userOptions == null ? void 0 : userOptions.parseSearch) ?? searchParams.defaultParseSearch
63
+ };
64
+ const [store, setStore] = reactivity.createStore(getInitialRouterState());
65
+ let navigationPromise;
66
+ let startedLoadingAt = Date.now();
67
+ let resolveNavigation = () => {};
68
+ function onFocus() {
69
+ router.load();
70
+ }
71
+ function buildRouteTree(rootRouteConfig) {
72
+ const recurseRoutes = (routeConfigs, parent) => {
73
+ return routeConfigs.map((routeConfig, i) => {
74
+ const routeOptions = routeConfig.options;
75
+ const route$1 = route.createRoute(routeConfig, routeOptions, i, parent, router);
76
+ const existingRoute = router.routesById[route$1.routeId];
77
+ if (existingRoute) {
78
+ if (process.env.NODE_ENV !== 'production') {
79
+ console.warn(`Duplicate routes found with id: ${String(route$1.routeId)}`, router.routesById, route$1);
80
+ }
81
+ throw new Error();
82
+ }
83
+ router.routesById[route$1.routeId] = route$1;
84
+ const children = routeConfig.children;
85
+ route$1.childRoutes = children != null && children.length ? recurseRoutes(children, route$1) : undefined;
86
+ return route$1;
87
+ });
88
+ };
89
+ const routes = recurseRoutes([rootRouteConfig]);
90
+ return routes[0];
91
+ }
92
+ function parseLocation(location, previousLocation) {
93
+ const parsedSearch = router.options.parseSearch(location.search);
94
+ return {
95
+ pathname: location.pathname,
96
+ searchStr: location.search,
97
+ search: sharedClone.sharedClone(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
98
+ hash: location.hash.split('#').reverse()[0] ?? '',
99
+ href: `${location.pathname}${location.search}${location.hash}`,
100
+ state: location.state,
101
+ key: location.key
102
+ };
103
+ }
104
+ function navigate(location) {
105
+ const next = router.buildNext(location);
106
+ return commitLocation(next, location.replace);
107
+ }
108
+ function buildLocation(dest) {
109
+ var _last, _dest$__preSearchFilt, _dest$__preSearchFilt2, _dest$__postSearchFil;
110
+ if (dest === void 0) {
111
+ dest = {};
112
+ }
113
+ const fromPathname = dest.fromCurrent ? store.latestLocation.pathname : dest.from ?? store.latestLocation.pathname;
114
+ let pathname = path.resolvePath(router.basepath ?? '/', fromPathname, `${dest.to ?? '.'}`);
115
+ const fromMatches = router.matchRoutes(store.latestLocation.pathname, {
116
+ strictParseParams: true
117
+ });
118
+ const toMatches = router.matchRoutes(pathname);
119
+ const prevParams = {
120
+ ...((_last = utils.last(fromMatches)) == null ? void 0 : _last.params)
121
+ };
122
+ let nextParams = (dest.params ?? true) === true ? prevParams : utils.functionalUpdate(dest.params, prevParams);
123
+ if (nextParams) {
124
+ toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
125
+ Object.assign({}, nextParams, fn(nextParams));
126
+ });
127
+ }
128
+ pathname = path.interpolatePath(pathname, nextParams ?? {});
129
+
130
+ // Pre filters first
131
+ const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), store.latestLocation.search) : store.latestLocation.search;
132
+
133
+ // Then the link/navigate function
134
+ const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
135
+ : dest.search ? utils.functionalUpdate(dest.search, preFilteredSearch) ?? {} // Updater
136
+ : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
137
+ : {};
138
+
139
+ // Then post filters
140
+ const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
141
+ const search = sharedClone.sharedClone(store.latestLocation.search, postFilteredSearch);
142
+ const searchStr = router.options.stringifySearch(search);
143
+ let hash = dest.hash === true ? store.latestLocation.hash : utils.functionalUpdate(dest.hash, store.latestLocation.hash);
144
+ hash = hash ? `#${hash}` : '';
145
+ return {
146
+ pathname,
147
+ search,
148
+ searchStr,
149
+ state: store.latestLocation.state,
150
+ hash,
151
+ href: `${pathname}${searchStr}${hash}`,
152
+ key: dest.key
153
+ };
154
+ }
155
+ function commitLocation(next, replace) {
156
+ const id = '' + Date.now() + Math.random();
157
+ let nextAction = 'replace';
158
+ if (!replace) {
159
+ nextAction = 'push';
160
+ }
161
+ const isSameUrl = parseLocation(router.history.location).href === next.href;
162
+ if (isSameUrl && !next.key) {
163
+ nextAction = 'replace';
164
+ }
165
+ router.history[nextAction]({
166
+ pathname: next.pathname,
167
+ hash: next.hash,
168
+ search: next.searchStr
169
+ }, {
170
+ id,
171
+ ...next.state
172
+ });
173
+ return navigationPromise = new Promise(resolve => {
174
+ const previousNavigationResolve = resolveNavigation;
175
+ resolveNavigation = () => {
176
+ previousNavigationResolve();
177
+ resolve();
178
+ };
179
+ });
180
+ }
181
+ const router = {
60
182
  types: undefined,
61
183
  // public api
62
- history,
184
+ history: (userOptions == null ? void 0 : userOptions.history) || createDefaultHistory(),
185
+ store,
186
+ setStore,
63
187
  options: originalOptions,
64
- listeners: [],
65
- // Resolved after construction
66
188
  basepath: '',
67
189
  routeTree: undefined,
68
190
  routesById: {},
69
- __location: undefined,
70
- //
71
- resolveNavigation: () => {},
72
- matchCache: {},
73
- state: getInitialRouterState(),
74
191
  reset: () => {
75
- router.state = getInitialRouterState();
76
- router.notify();
77
- },
78
- startedLoadingAt: Date.now(),
79
- subscribe: listener => {
80
- router.listeners.push(listener);
81
- return () => {
82
- router.listeners = router.listeners.filter(x => x !== listener);
83
- };
192
+ setStore(s => Object.assign(s, getInitialRouterState()));
84
193
  },
85
194
  getRoute: id => {
86
195
  return router.routesById[id];
87
196
  },
88
- notify: () => {
89
- const isFetching = router.state.status === 'loading' || router.state.matches.some(d => d.isFetching);
90
- const isPreloading = Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId));
91
- if (router.state.isFetching !== isFetching || router.state.isPreloading !== isPreloading) {
92
- router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
93
- isFetching,
94
- isPreloading
95
- });
96
- }
97
- cascadeLoaderData(router.state.matches);
98
- router.listeners.forEach(listener => listener(router));
99
- },
100
197
  dehydrate: () => {
101
198
  return {
102
- location: router.__location,
103
- state: _rollupPluginBabelHelpers["extends"]({}, utils.pick(router.state, ['status', 'location', 'lastUpdated', 'location']), {
104
- matches: router.state.matches.map(match => utils.pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
105
- }),
199
+ store: {
200
+ ...utils.pick(store, ['latestLocation', 'currentLocation', 'status', 'lastUpdated']),
201
+ currentMatches: store.currentMatches.map(match => ({
202
+ matchId: match.matchId,
203
+ store: utils.pick(match.store, ['status', 'routeLoaderData', 'isInvalid', 'invalidAt'])
204
+ }))
205
+ },
106
206
  context: router.options.context
107
207
  };
108
208
  },
109
- hydrate: dehydratedState => {
110
- // Update the location
111
- router.__location = dehydratedState.location;
112
-
113
- // Update the context
114
- router.options.context = dehydratedState.context;
209
+ hydrate: dehydratedRouter => {
210
+ setStore(s => {
211
+ // Update the context TODO: make this part of state?
212
+ router.options.context = dehydratedRouter.context;
115
213
 
116
- // Match the routes
117
- const matches = router.matchRoutes(router.__location.pathname, {
118
- strictParseParams: true
119
- });
120
- matches.forEach((match, index) => {
121
- const dehydratedMatch = dehydratedState.state.matches[index];
122
- invariant__default["default"](dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
123
- Object.assign(match, dehydratedMatch);
124
- });
125
- matches.forEach(match => match.__.validate());
126
- router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, dehydratedState, {
127
- matches
214
+ // Match the routes
215
+ const currentMatches = router.matchRoutes(dehydratedRouter.store.latestLocation.pathname, {
216
+ strictParseParams: true
217
+ });
218
+ currentMatches.forEach((match, index) => {
219
+ const dehydratedMatch = dehydratedRouter.store.currentMatches[index];
220
+ invariant__default["default"](dehydratedMatch && dehydratedMatch.matchId === match.matchId, 'Oh no! There was a hydration mismatch when attempting to restore the state of the router! 😬');
221
+ Object.assign(match, dehydratedMatch);
222
+ });
223
+ currentMatches.forEach(match => match.__.validate());
224
+ Object.assign(s, {
225
+ ...dehydratedRouter.store,
226
+ currentMatches
227
+ });
128
228
  });
129
229
  },
130
230
  mount: () => {
131
- router.__.buildLocation({
132
- to: '.',
133
- search: true,
134
- hash: true
135
- });
136
-
137
- // If the current location isn't updated, trigger a navigation
138
- // to the current location. Otherwise, load the current location.
139
- // if (next.href !== router.__location.href) {
140
- // router.__.commitLocation(next, true)
141
- // }
142
-
143
- if (!router.state.matches.length) {
144
- router.load();
145
- }
146
- const unsub = router.history.listen(event => {
147
- router.load(router.__.parseLocation(event.location, router.__location));
148
- });
231
+ // Mount only does anything on the client
232
+ if (!isServer) {
233
+ // If the router matches are empty, load the matches
234
+ if (!store.currentMatches.length) {
235
+ router.load();
236
+ }
237
+ const unsub = router.history.listen(event => {
238
+ router.load(parseLocation(event.location, store.latestLocation));
239
+ });
149
240
 
150
- // addEventListener does not exist in React Native, but window does
151
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
152
- if (!isServer && window.addEventListener) {
153
- // Listen to visibillitychange and focus
154
- window.addEventListener('visibilitychange', router.onFocus, false);
155
- window.addEventListener('focus', router.onFocus, false);
156
- }
157
- return () => {
158
- unsub();
159
- if (!isServer && window.removeEventListener) {
160
- // Be sure to unsubscribe if a new handler is set
161
- window.removeEventListener('visibilitychange', router.onFocus);
162
- window.removeEventListener('focus', router.onFocus);
241
+ // addEventListener does not exist in React Native, but window does
242
+ // In the future, we might need to invert control here for more adapters
243
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
244
+ if (window.addEventListener) {
245
+ // Listen to visibilitychange and focus
246
+ window.addEventListener('visibilitychange', onFocus, false);
247
+ window.addEventListener('focus', onFocus, false);
163
248
  }
164
- };
165
- },
166
- onFocus: () => {
167
- router.load();
249
+ return () => {
250
+ unsub();
251
+ if (window.removeEventListener) {
252
+ // Be sure to unsubscribe if a new handler is set
253
+ window.removeEventListener('visibilitychange', onFocus);
254
+ window.removeEventListener('focus', onFocus);
255
+ }
256
+ };
257
+ }
258
+ return () => {};
168
259
  },
169
260
  update: opts => {
170
- var _trimPath;
171
261
  const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
172
- if (!router.__location || newHistory) {
262
+ if (!store.latestLocation || newHistory) {
173
263
  if (opts != null && opts.history) {
174
264
  router.history = opts.history;
175
265
  }
176
- router.__location = router.__.parseLocation(router.history.location);
177
- router.state.location = router.__location;
266
+ setStore(s => {
267
+ s.latestLocation = parseLocation(router.history.location);
268
+ s.currentLocation = s.latestLocation;
269
+ });
178
270
  }
179
271
  Object.assign(router.options, opts);
180
272
  const {
181
273
  basepath,
182
274
  routeConfig
183
275
  } = router.options;
184
- router.basepath = "/" + ((_trimPath = path.trimPath(basepath != null ? basepath : '')) != null ? _trimPath : '');
276
+ router.basepath = `/${path.trimPath(basepath ?? '') ?? ''}`;
185
277
  if (routeConfig) {
186
278
  router.routesById = {};
187
- router.routeTree = router.__.buildRouteTree(routeConfig);
279
+ router.routeTree = buildRouteTree(routeConfig);
188
280
  }
189
281
  return router;
190
282
  },
191
283
  cancelMatches: () => {
192
- var _router$state$pending, _router$state$pending2;
193
- [...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 => {
284
+ [...store.currentMatches, ...(store.pendingMatches || [])].forEach(match => {
194
285
  match.cancel();
195
286
  });
196
287
  },
197
288
  load: async next => {
198
- const id = Math.random();
199
- router.startedLoadingAt = id;
200
- if (next) {
201
- // Ingest the new location
202
- router.__location = next;
203
- }
289
+ let now = Date.now();
290
+ const startedAt = now;
291
+ startedLoadingAt = startedAt;
204
292
 
205
293
  // Cancel any pending matches
206
294
  router.cancelMatches();
295
+ let matches;
296
+ reactivity.batch(() => {
297
+ if (next) {
298
+ // Ingest the new location
299
+ setStore(s => {
300
+ s.latestLocation = next;
301
+ });
302
+ }
207
303
 
208
- // Match the routes
209
- const matches = router.matchRoutes(router.__location.pathname, {
210
- strictParseParams: true
211
- });
212
- if (typeof document !== 'undefined') {
213
- router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
214
- pending: {
215
- matches: matches,
216
- location: router.__location
217
- },
218
- status: 'loading'
304
+ // Match the routes
305
+ matches = router.matchRoutes(store.latestLocation.pathname, {
306
+ strictParseParams: true
219
307
  });
220
- } else {
221
- router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
222
- matches: matches,
223
- location: router.__location,
224
- status: 'loading'
308
+ console.log('set loading', matches);
309
+ setStore(s => {
310
+ s.status = 'loading';
311
+ s.pendingMatches = matches;
312
+ s.pendingLocation = store.latestLocation;
225
313
  });
226
- }
314
+ });
227
315
 
228
- // Check if each match middleware to see if the route can be accessed
316
+ // Load the matches
229
317
  try {
230
- await Promise.all(matches.map(match => match.options.beforeLoad == null ? void 0 : match.options.beforeLoad({
231
- router: router,
232
- match
233
- })));
318
+ await router.loadMatches(matches);
234
319
  } catch (err) {
235
- console.info(err);
236
- invariant__default["default"](false, "A route's beforeLoad middleware failed! \uD83D\uDC46");
320
+ console.log(err);
321
+ invariant__default["default"](false, 'Matches failed to load due to error above ☝️. Navigation cancelled!');
237
322
  }
238
- router.notify();
239
-
240
- // Load the matches
241
- await router.loadMatches(matches);
242
- if (router.startedLoadingAt !== id) {
243
- // Ignore side-effects of match loading
244
- return router.navigationPromise;
323
+ if (startedLoadingAt !== startedAt) {
324
+ // Ignore side-effects of outdated side-effects
325
+ return navigationPromise;
245
326
  }
246
- const previousMatches = router.state.matches;
327
+ const previousMatches = store.currentMatches;
247
328
  const exiting = [],
248
329
  staying = [];
249
330
  previousMatches.forEach(d => {
@@ -256,22 +337,21 @@ function createRouter(userOptions) {
256
337
  const entering = matches.filter(d => {
257
338
  return !previousMatches.find(dd => dd.matchId === d.matchId);
258
339
  });
259
- const now = Date.now();
340
+ now = Date.now();
260
341
  exiting.forEach(d => {
261
- var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
262
342
  d.__.onExit == null ? void 0 : d.__.onExit({
263
343
  params: d.params,
264
- search: d.routeSearch
344
+ search: d.store.routeSearch
265
345
  });
266
346
 
267
347
  // Clear idle error states when match leaves
268
- if (d.status === 'error' && !d.isFetching) {
269
- d.status = 'idle';
270
- d.error = undefined;
348
+ if (d.store.status === 'error' && !d.store.isFetching) {
349
+ d.store.status = 'idle';
350
+ d.store.error = undefined;
271
351
  }
272
- 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);
352
+ const gc = Math.max(d.options.loaderGcMaxAge ?? router.options.defaultLoaderGcMaxAge ?? 0, d.options.loaderMaxAge ?? router.options.defaultLoaderMaxAge ?? 0);
273
353
  if (gc > 0) {
274
- router.matchCache[d.matchId] = {
354
+ store.matchCache[d.matchId] = {
275
355
  gc: gc == Infinity ? Number.MAX_SAFE_INTEGER : now + gc,
276
356
  match: d
277
357
  };
@@ -280,58 +360,64 @@ function createRouter(userOptions) {
280
360
  staying.forEach(d => {
281
361
  d.options.onTransition == null ? void 0 : d.options.onTransition({
282
362
  params: d.params,
283
- search: d.routeSearch
363
+ search: d.store.routeSearch
284
364
  });
285
365
  });
286
366
  entering.forEach(d => {
287
367
  d.__.onExit = d.options.onLoaded == null ? void 0 : d.options.onLoaded({
288
368
  params: d.params,
289
- search: d.search
369
+ search: d.store.search
290
370
  });
291
- delete router.matchCache[d.matchId];
371
+ delete store.matchCache[d.matchId];
292
372
  });
293
- if (router.startedLoadingAt !== id) {
373
+ if (startedLoadingAt !== startedAt) {
294
374
  // Ignore side-effects of match loading
295
375
  return;
296
376
  }
297
377
  matches.forEach(match => {
298
378
  // Clear actions
299
379
  if (match.action) {
380
+ // TODO: Check reactivity here
300
381
  match.action.current = undefined;
301
382
  match.action.submissions = [];
302
383
  }
303
384
  });
304
- router.state = _rollupPluginBabelHelpers["extends"]({}, router.state, {
305
- location: router.__location,
306
- matches,
307
- pending: undefined,
308
- status: 'idle'
385
+ setStore(s => {
386
+ console.log('set', matches);
387
+ Object.assign(s, {
388
+ status: 'idle',
389
+ currentLocation: store.latestLocation,
390
+ currentMatches: matches,
391
+ pendingLocation: undefined,
392
+ pendingMatches: undefined
393
+ });
309
394
  });
310
- router.notify();
311
- router.resolveNavigation();
395
+ resolveNavigation();
312
396
  },
313
397
  cleanMatchCache: () => {
314
398
  const now = Date.now();
315
- Object.keys(router.matchCache).forEach(matchId => {
316
- const entry = router.matchCache[matchId];
399
+ setStore(s => {
400
+ Object.keys(s.matchCache).forEach(matchId => {
401
+ const entry = s.matchCache[matchId];
317
402
 
318
- // Don't remove loading matches
319
- if (entry.match.status === 'loading') {
320
- return;
321
- }
403
+ // Don't remove loading matches
404
+ if (entry.match.store.status === 'loading') {
405
+ return;
406
+ }
322
407
 
323
- // Do not remove successful matches that are still valid
324
- if (entry.gc > 0 && entry.gc > now) {
325
- return;
326
- }
408
+ // Do not remove successful matches that are still valid
409
+ if (entry.gc > 0 && entry.gc > now) {
410
+ return;
411
+ }
327
412
 
328
- // Everything else gets removed
329
- delete router.matchCache[matchId];
413
+ // Everything else gets removed
414
+ delete s.matchCache[matchId];
415
+ });
330
416
  });
331
417
  },
332
- loadRoute: async function loadRoute(navigateOpts) {
418
+ loadRoute: async function (navigateOpts) {
333
419
  if (navigateOpts === void 0) {
334
- navigateOpts = router.__location;
420
+ navigateOpts = store.latestLocation;
335
421
  }
336
422
  const next = router.buildNext(navigateOpts);
337
423
  const matches = router.matchRoutes(next.pathname, {
@@ -340,10 +426,9 @@ function createRouter(userOptions) {
340
426
  await router.loadMatches(matches);
341
427
  return matches;
342
428
  },
343
- preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
344
- var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
429
+ preloadRoute: async function (navigateOpts, loaderOpts) {
345
430
  if (navigateOpts === void 0) {
346
- navigateOpts = router.__location;
431
+ navigateOpts = store.latestLocation;
347
432
  }
348
433
  const next = router.buildNext(navigateOpts);
349
434
  const matches = router.matchRoutes(next.pathname, {
@@ -351,28 +436,27 @@ function createRouter(userOptions) {
351
436
  });
352
437
  await router.loadMatches(matches, {
353
438
  preload: true,
354
- maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
355
- gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
439
+ maxAge: loaderOpts.maxAge ?? router.options.defaultPreloadMaxAge ?? router.options.defaultLoaderMaxAge ?? 0,
440
+ gcMaxAge: loaderOpts.gcMaxAge ?? router.options.defaultPreloadGcMaxAge ?? router.options.defaultLoaderGcMaxAge ?? 0
356
441
  });
357
442
  return matches;
358
443
  },
359
444
  matchRoutes: (pathname, opts) => {
360
- var _router$state$pending3, _router$state$pending4;
361
445
  router.cleanMatchCache();
362
446
  const matches = [];
363
447
  if (!router.routeTree) {
364
448
  return matches;
365
449
  }
366
- 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 : [])];
450
+ const existingMatches = [...store.currentMatches, ...(store.pendingMatches ?? [])];
367
451
  const recurse = async routes => {
368
- var _parentMatch$params, _router$options$filte, _foundRoute$childRout;
452
+ var _foundRoute$childRout;
369
453
  const parentMatch = utils.last(matches);
370
- let params = (_parentMatch$params = parentMatch == null ? void 0 : parentMatch.params) != null ? _parentMatch$params : {};
371
- const filteredRoutes = (_router$options$filte = router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) != null ? _router$options$filte : routes;
454
+ let params = (parentMatch == null ? void 0 : parentMatch.params) ?? {};
455
+ const filteredRoutes = (router.options.filterRoutes == null ? void 0 : router.options.filterRoutes(routes)) ?? routes;
372
456
  let foundRoutes = [];
373
457
  const findMatchInRoutes = (parentRoutes, routes) => {
374
458
  routes.some(route => {
375
- var _route$childRoutes, _route$childRoutes2, _route$options$caseSe;
459
+ var _route$childRoutes, _route$childRoutes2;
376
460
  if (!route.routePath && (_route$childRoutes = route.childRoutes) != null && _route$childRoutes.length) {
377
461
  return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
378
462
  }
@@ -380,20 +464,21 @@ function createRouter(userOptions) {
380
464
  const matchParams = path.matchPathname(router.basepath, pathname, {
381
465
  to: route.fullPath,
382
466
  fuzzy,
383
- caseSensitive: (_route$options$caseSe = route.options.caseSensitive) != null ? _route$options$caseSe : router.options.caseSensitive
467
+ caseSensitive: route.options.caseSensitive ?? router.options.caseSensitive
384
468
  });
385
- console.log(router.basepath, route.fullPath, fuzzy, pathname, matchParams);
386
469
  if (matchParams) {
387
470
  let parsedParams;
388
471
  try {
389
- var _route$options$parseP;
390
- parsedParams = (_route$options$parseP = route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) != null ? _route$options$parseP : matchParams;
472
+ parsedParams = (route.options.parseParams == null ? void 0 : route.options.parseParams(matchParams)) ?? matchParams;
391
473
  } catch (err) {
392
474
  if (opts != null && opts.strictParseParams) {
393
475
  throw err;
394
476
  }
395
477
  }
396
- params = _rollupPluginBabelHelpers["extends"]({}, params, parsedParams);
478
+ params = {
479
+ ...params,
480
+ ...parsedParams
481
+ };
397
482
  }
398
483
  if (!!matchParams) {
399
484
  foundRoutes = [...parentRoutes, route];
@@ -407,10 +492,10 @@ function createRouter(userOptions) {
407
492
  return;
408
493
  }
409
494
  foundRoutes.forEach(foundRoute => {
410
- var _router$matchCache$ma;
495
+ var _store$matchCache$mat;
411
496
  const interpolatedPath = path.interpolatePath(foundRoute.routePath, params);
412
497
  const matchId = path.interpolatePath(foundRoute.routeId, params, true);
413
- const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || routeMatch.createRouteMatch(router, foundRoute, {
498
+ const match = existingMatches.find(d => d.matchId === matchId) || ((_store$matchCache$mat = store.matchCache[matchId]) == null ? void 0 : _store$matchCache$mat.match) || routeMatch.createRouteMatch(router, foundRoute, {
414
499
  parentMatch,
415
500
  matchId,
416
501
  params,
@@ -424,40 +509,56 @@ function createRouter(userOptions) {
424
509
  }
425
510
  };
426
511
  recurse([router.routeTree]);
427
- cascadeLoaderData(matches);
512
+ linkMatches(matches);
428
513
  return matches;
429
514
  },
430
515
  loadMatches: async (resolvedMatches, loaderOpts) => {
431
- const matchPromises = resolvedMatches.map(async match => {
432
- var _search$__data;
516
+ resolvedMatches.forEach(async match => {
433
517
  // Validate the match (loads search params etc)
434
518
  match.__.validate();
435
- const search = match.search;
519
+ });
520
+
521
+ // Check each match middleware to see if the route can be accessed
522
+ await Promise.all(resolvedMatches.map(async match => {
523
+ try {
524
+ await (match.options.beforeLoad == null ? void 0 : match.options.beforeLoad({
525
+ router: router,
526
+ match
527
+ }));
528
+ } catch (err) {
529
+ if (!(loaderOpts != null && loaderOpts.preload)) {
530
+ match.options.onLoadError == null ? void 0 : match.options.onLoadError(err);
531
+ }
532
+ throw err;
533
+ }
534
+ }));
535
+ const matchPromises = resolvedMatches.map(async match => {
536
+ var _search$__data;
537
+ const search = match.store.search;
436
538
  if ((_search$__data = search.__data) != null && _search$__data.matchId && search.__data.matchId !== match.matchId) {
437
539
  return;
438
540
  }
439
541
  match.load(loaderOpts);
440
- if (match.status !== 'success' && match.__.loadPromise) {
542
+ if (match.store.status !== 'success' && match.__.loadPromise) {
441
543
  // Wait for the first sign of activity from the match
442
544
  await match.__.loadPromise;
443
545
  }
444
546
  });
445
- router.notify();
446
547
  await Promise.all(matchPromises);
447
548
  },
448
549
  loadMatchData: async routeMatch => {
449
550
  if (isServer || !router.options.useServerData) {
450
- var _await$routeMatch$opt;
451
- return (_await$routeMatch$opt = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
551
+ return (await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
452
552
  // parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
453
553
  params: routeMatch.params,
454
- search: routeMatch.routeSearch,
554
+ search: routeMatch.store.routeSearch,
455
555
  signal: routeMatch.__.abortController.signal
456
- }))) != null ? _await$routeMatch$opt : {};
556
+ }))) || {};
457
557
  } else {
458
558
  const next = router.buildNext({
459
559
  to: '.',
460
- search: d => _rollupPluginBabelHelpers["extends"]({}, d != null ? d : {}, {
560
+ search: d => ({
561
+ ...(d ?? {}),
461
562
  __data: {
462
563
  matchId: routeMatch.matchId
463
564
  }
@@ -486,16 +587,15 @@ function createRouter(userOptions) {
486
587
  }
487
588
  },
488
589
  invalidateRoute: opts => {
489
- var _router$state$pending5, _router$state$pending6;
490
590
  const next = router.buildNext(opts);
491
591
  const unloadedMatchIds = router.matchRoutes(next.pathname).map(d => d.matchId);
492
- [...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 => {
592
+ [...store.currentMatches, ...(store.pendingMatches ?? [])].forEach(match => {
493
593
  if (unloadedMatchIds.includes(match.matchId)) {
494
594
  match.invalidate();
495
595
  }
496
596
  });
497
597
  },
498
- reload: () => router.__.navigate({
598
+ reload: () => navigate({
499
599
  fromCurrent: true,
500
600
  replace: true,
501
601
  search: true
@@ -504,27 +604,28 @@ function createRouter(userOptions) {
504
604
  return path.resolvePath(router.basepath, from, path.cleanPath(path$1));
505
605
  },
506
606
  matchRoute: (location, opts) => {
507
- var _location$from;
508
607
  // const location = router.buildNext(opts)
509
608
 
510
- location = _rollupPluginBabelHelpers["extends"]({}, location, {
511
- to: location.to ? router.resolvePath((_location$from = location.from) != null ? _location$from : '', location.to) : undefined
512
- });
609
+ location = {
610
+ ...location,
611
+ to: location.to ? router.resolvePath(location.from ?? '', location.to) : undefined
612
+ };
513
613
  const next = router.buildNext(location);
514
614
  if (opts != null && opts.pending) {
515
- var _router$state$pending7;
516
- if (!((_router$state$pending7 = router.state.pending) != null && _router$state$pending7.location)) {
615
+ if (!store.pendingLocation) {
517
616
  return false;
518
617
  }
519
- return !!path.matchPathname(router.basepath, router.state.pending.location.pathname, _rollupPluginBabelHelpers["extends"]({}, opts, {
618
+ return !!path.matchPathname(router.basepath, store.pendingLocation.pathname, {
619
+ ...opts,
520
620
  to: next.pathname
521
- }));
621
+ });
522
622
  }
523
- return !!path.matchPathname(router.basepath, router.state.location.pathname, _rollupPluginBabelHelpers["extends"]({}, opts, {
623
+ return path.matchPathname(router.basepath, store.currentLocation.pathname, {
624
+ ...opts,
524
625
  to: next.pathname
525
- }));
626
+ });
526
627
  },
527
- navigate: async _ref7 => {
628
+ navigate: async _ref => {
528
629
  let {
529
630
  from,
530
631
  to = '.',
@@ -532,7 +633,7 @@ function createRouter(userOptions) {
532
633
  hash,
533
634
  replace,
534
635
  params
535
- } = _ref7;
636
+ } = _ref;
536
637
  // If this link simply reloads the current route,
537
638
  // make sure it has a new key so it will trigger a data refresh
538
639
 
@@ -542,11 +643,11 @@ function createRouter(userOptions) {
542
643
  const fromString = String(from);
543
644
  let isExternal;
544
645
  try {
545
- new URL("" + toString);
646
+ new URL(`${toString}`);
546
647
  isExternal = true;
547
648
  } catch (e) {}
548
649
  invariant__default["default"](!isExternal, 'Attempting to navigate to external url with router.navigate!');
549
- return router.__.navigate({
650
+ return navigate({
550
651
  from: fromString,
551
652
  to: toString,
552
653
  search,
@@ -555,8 +656,7 @@ function createRouter(userOptions) {
555
656
  params
556
657
  });
557
658
  },
558
- buildLink: _ref8 => {
559
- var _preload, _ref9;
659
+ buildLink: _ref2 => {
560
660
  let {
561
661
  from,
562
662
  to = '.',
@@ -571,7 +671,7 @@ function createRouter(userOptions) {
571
671
  preloadGcMaxAge: userPreloadGcMaxAge,
572
672
  preloadDelay: userPreloadDelay,
573
673
  disabled
574
- } = _ref8;
674
+ } = _ref2;
575
675
  // If this link simply reloads the current route,
576
676
  // make sure it has a new key so it will trigger a data refresh
577
677
 
@@ -579,7 +679,7 @@ function createRouter(userOptions) {
579
679
  // null for LinkUtils
580
680
 
581
681
  try {
582
- new URL("" + to);
682
+ new URL(`${to}`);
583
683
  return {
584
684
  type: 'external',
585
685
  href: to
@@ -594,15 +694,15 @@ function createRouter(userOptions) {
594
694
  replace
595
695
  };
596
696
  const next = router.buildNext(nextOpts);
597
- preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
598
- const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0;
697
+ preload = preload ?? router.options.defaultPreload;
698
+ const preloadDelay = userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0;
599
699
 
600
700
  // Compare path/hash for matches
601
- const pathIsEqual = router.state.location.pathname === next.pathname;
602
- const currentPathSplit = router.state.location.pathname.split('/');
701
+ const pathIsEqual = store.currentLocation.pathname === next.pathname;
702
+ const currentPathSplit = store.currentLocation.pathname.split('/');
603
703
  const nextPathSplit = next.pathname.split('/');
604
704
  const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
605
- const hashIsEqual = router.state.location.hash === next.hash;
705
+ const hashIsEqual = store.currentLocation.hash === next.hash;
606
706
  // Combine the matches based on user options
607
707
  const pathTest = activeOptions != null && activeOptions.exact ? pathIsEqual : pathIsFuzzyEqual;
608
708
  const hashTest = activeOptions != null && activeOptions.includeHash ? hashIsEqual : true;
@@ -618,8 +718,8 @@ function createRouter(userOptions) {
618
718
  router.invalidateRoute(nextOpts);
619
719
  }
620
720
 
621
- // All is well? Navigate!)
622
- router.__.navigate(nextOpts);
721
+ // All is well? Navigate!
722
+ navigate(nextOpts);
623
723
  }
624
724
  };
625
725
 
@@ -629,6 +729,9 @@ function createRouter(userOptions) {
629
729
  router.preloadRoute(nextOpts, {
630
730
  maxAge: userPreloadMaxAge,
631
731
  gcMaxAge: userPreloadGcMaxAge
732
+ }).catch(err => {
733
+ console.log(err);
734
+ console.warn('Error preloading route! ☝️');
632
735
  });
633
736
  }
634
737
  };
@@ -643,6 +746,9 @@ function createRouter(userOptions) {
643
746
  router.preloadRoute(nextOpts, {
644
747
  maxAge: userPreloadMaxAge,
645
748
  gcMaxAge: userPreloadGcMaxAge
749
+ }).catch(err => {
750
+ console.log(err);
751
+ console.warn('Error preloading route! ☝️');
646
752
  });
647
753
  }, preloadDelay);
648
754
  }
@@ -666,143 +772,15 @@ function createRouter(userOptions) {
666
772
  };
667
773
  },
668
774
  buildNext: opts => {
669
- const next = router.__.buildLocation(opts);
775
+ const next = buildLocation(opts);
670
776
  const matches = router.matchRoutes(next.pathname);
671
- const __preSearchFilters = matches.map(match => {
672
- var _match$options$preSea;
673
- return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
674
- }).flat().filter(Boolean);
675
- const __postSearchFilters = matches.map(match => {
676
- var _match$options$postSe;
677
- return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
678
- }).flat().filter(Boolean);
679
- return router.__.buildLocation(_rollupPluginBabelHelpers["extends"]({}, opts, {
777
+ const __preSearchFilters = matches.map(match => match.options.preSearchFilters ?? []).flat().filter(Boolean);
778
+ const __postSearchFilters = matches.map(match => match.options.postSearchFilters ?? []).flat().filter(Boolean);
779
+ return buildLocation({
780
+ ...opts,
680
781
  __preSearchFilters,
681
782
  __postSearchFilters
682
- }));
683
- },
684
- __: {
685
- buildRouteTree: rootRouteConfig => {
686
- const recurseRoutes = (routeConfigs, parent) => {
687
- return routeConfigs.map(routeConfig => {
688
- const routeOptions = routeConfig.options;
689
- const route$1 = route.createRoute(routeConfig, routeOptions, parent, router);
690
- const existingRoute = router.routesById[route$1.routeId];
691
- if (existingRoute) {
692
- if (process.env.NODE_ENV !== 'production') {
693
- console.warn("Duplicate routes found with id: " + String(route$1.routeId), router.routesById, route$1);
694
- }
695
- throw new Error();
696
- }
697
- router.routesById[route$1.routeId] = route$1;
698
- const children = routeConfig.children;
699
- route$1.childRoutes = children != null && children.length ? recurseRoutes(children, route$1) : undefined;
700
- return route$1;
701
- });
702
- };
703
- const routes = recurseRoutes([rootRouteConfig]);
704
- return routes[0];
705
- },
706
- parseLocation: (location, previousLocation) => {
707
- var _location$hash$split$;
708
- const parsedSearch = router.options.parseSearch(location.search);
709
- return {
710
- pathname: location.pathname,
711
- searchStr: location.search,
712
- search: utils.replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
713
- hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
714
- href: "" + location.pathname + location.search + location.hash,
715
- state: location.state,
716
- key: location.key
717
- };
718
- },
719
- navigate: location => {
720
- const next = router.buildNext(location);
721
- return router.__.commitLocation(next, location.replace);
722
- },
723
- buildLocation: function buildLocation(dest) {
724
- var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
725
- if (dest === void 0) {
726
- dest = {};
727
- }
728
- const fromPathname = dest.fromCurrent ? router.__location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.__location.pathname;
729
- let pathname = path.resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
730
- const fromMatches = router.matchRoutes(router.__location.pathname, {
731
- strictParseParams: true
732
- });
733
- const toMatches = router.matchRoutes(pathname);
734
- const prevParams = _rollupPluginBabelHelpers["extends"]({}, (_last = utils.last(fromMatches)) == null ? void 0 : _last.params);
735
- let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : utils.functionalUpdate(dest.params, prevParams);
736
- if (nextParams) {
737
- toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
738
- Object.assign({}, nextParams, fn(nextParams));
739
- });
740
- }
741
- pathname = path.interpolatePath(pathname, nextParams != null ? nextParams : {});
742
-
743
- // Pre filters first
744
- const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), router.__location.search) : router.__location.search;
745
-
746
- // Then the link/navigate function
747
- const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
748
- : dest.search ? (_functionalUpdate = utils.functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
749
- : (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
750
- : {};
751
-
752
- // Then post filters
753
- const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
754
- const search = utils.replaceEqualDeep(router.__location.search, postFilteredSearch);
755
- const searchStr = router.options.stringifySearch(search);
756
- let hash = dest.hash === true ? router.__location.hash : utils.functionalUpdate(dest.hash, router.__location.hash);
757
- hash = hash ? "#" + hash : '';
758
- return {
759
- pathname,
760
- search,
761
- searchStr,
762
- state: router.__location.state,
763
- hash,
764
- href: "" + pathname + searchStr + hash,
765
- key: dest.key
766
- };
767
- },
768
- commitLocation: (next, replace) => {
769
- const id = '' + Date.now() + Math.random();
770
- if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
771
- let nextAction = 'replace';
772
- if (!replace) {
773
- nextAction = 'push';
774
- }
775
- const isSameUrl = router.__.parseLocation(history.location).href === next.href;
776
- if (isSameUrl && !next.key) {
777
- nextAction = 'replace';
778
- }
779
- if (nextAction === 'replace') {
780
- history.replace({
781
- pathname: next.pathname,
782
- hash: next.hash,
783
- search: next.searchStr
784
- }, _rollupPluginBabelHelpers["extends"]({
785
- id
786
- }, next.state));
787
- } else {
788
- history.push({
789
- pathname: next.pathname,
790
- hash: next.hash,
791
- search: next.searchStr
792
- }, {
793
- id
794
- });
795
- }
796
- router.navigationPromise = new Promise(resolve => {
797
- const previousNavigationResolve = router.resolveNavigation;
798
- router.resolveNavigation = () => {
799
- previousNavigationResolve();
800
- resolve();
801
- delete router.navigationPromise;
802
- };
803
- });
804
- return router.navigationPromise;
805
- }
783
+ });
806
784
  }
807
785
  };
808
786
  router.update(userOptions);
@@ -814,11 +792,13 @@ function createRouter(userOptions) {
814
792
  function isCtrlEvent(e) {
815
793
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
816
794
  }
817
- function cascadeLoaderData(matches) {
795
+ function linkMatches(matches) {
818
796
  matches.forEach((match, index) => {
819
797
  const parent = matches[index - 1];
820
798
  if (parent) {
821
- match.loaderData = utils.replaceEqualDeep(match.loaderData, _rollupPluginBabelHelpers["extends"]({}, parent.loaderData, match.routeLoaderData));
799
+ match.__.setParentMatch(parent);
800
+ } else {
801
+ match.__.setParentMatch(undefined);
822
802
  }
823
803
  });
824
804
  }