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