@tanstack/router-core 0.0.1-beta.50 → 0.0.1-beta.52

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.
@@ -133,7 +133,7 @@ interface RouterOptions<TRouteConfig extends AnyRouteConfig, TRouterContext> {
133
133
  routeConfig?: TRouteConfig;
134
134
  basepath?: string;
135
135
  useServerData?: boolean;
136
- createRouter?: (router: AnyRouter) => void;
136
+ Router?: (router: AnyRouter) => void;
137
137
  createRoute?: (opts: {
138
138
  route: AnyRoute;
139
139
  router: AnyRouter;
@@ -221,7 +221,7 @@ interface DehydratedRouter<TRouterContext = unknown> {
221
221
  }
222
222
  type MatchCache = Record<string, MatchCacheEntry>;
223
223
  interface DehydratedRouteMatch {
224
- matchId: string;
224
+ id: string;
225
225
  state: Pick<RouteMatchStore<any, any>, 'status' | 'routeLoaderData' | 'invalid' | 'invalidAt'>;
226
226
  }
227
227
  interface RouterContext {
@@ -316,10 +316,11 @@ declare class RouteMatch<TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRoute
316
316
  search: TRouteInfo['fullSearchSchema'];
317
317
  }) => void);
318
318
  constructor(router: AnyRouter, route: Route<TAllRouteInfo, TRouteInfo>, opts: {
319
- matchId: string;
319
+ id: string;
320
320
  params: TRouteInfo['allParams'];
321
321
  pathname: string;
322
322
  });
323
+ setLoaderData: (loaderData: TRouteInfo['routeLoaderData']) => void;
323
324
  cancel: () => void;
324
325
  load: (loaderOpts?: {
325
326
  preload: true;
@@ -119,13 +119,8 @@
119
119
  const getLocation = () => parseLocation(entries[index], currentState);
120
120
  return createHistory({
121
121
  getLocation,
122
- listener: onUpdate => {
123
- window.addEventListener(popStateEvent, onUpdate);
124
- // We might need to handle the hashchange event in the future
125
- // window.addEventListener(hashChangeEvent, onUpdate)
126
- return () => {
127
- window.removeEventListener(popStateEvent, onUpdate);
128
- };
122
+ listener: () => {
123
+ return () => {};
129
124
  },
130
125
  pushState: (path, state) => {
131
126
  currentState = {
@@ -678,7 +673,7 @@
678
673
  Object.assign(this, {
679
674
  route,
680
675
  router,
681
- matchId: opts.matchId,
676
+ id: opts.id,
682
677
  pathname: opts.pathname,
683
678
  params: opts.params,
684
679
  store: createStore({
@@ -696,7 +691,7 @@
696
691
  this.store.setState(s => s.status = 'success');
697
692
  }
698
693
  }
699
- #setLoaderData = loaderData => {
694
+ setLoaderData = loaderData => {
700
695
  batch(() => {
701
696
  this.store.setState(s => {
702
697
  s.routeLoaderData = loaderData;
@@ -771,7 +766,7 @@
771
766
  if (this.route.options.loader) {
772
767
  const data = await this.router.loadMatchData(this);
773
768
  if (latestPromise = checkLatest()) return latestPromise;
774
- this.#setLoaderData(data);
769
+ this.setLoaderData(data);
775
770
  }
776
771
  this.store.setState(s => {
777
772
  s.error = undefined;
@@ -956,8 +951,7 @@
956
951
  throw new Error('Failed to fetch match data');
957
952
  };
958
953
  class Router {
959
- // __location: Location<TAllRouteInfo['fullSearchSchema']>
960
-
954
+ #unsubHistory;
961
955
  startedLoadingAt = Date.now();
962
956
  resolveNavigation = () => {};
963
957
  constructor(options) {
@@ -972,13 +966,12 @@
972
966
  parseSearch: options?.parseSearch ?? defaultParseSearch,
973
967
  fetchServerDataFn: options?.fetchServerDataFn ?? defaultFetchServerDataFn
974
968
  };
975
- this.history = this.options?.history ?? createBrowserHistory();
976
969
  this.store = createStore(getInitialRouterState());
977
970
  this.basepath = '';
978
971
  this.update(options);
979
972
 
980
973
  // Allow frameworks to hook into the router creation
981
- this.options.createRouter?.(this);
974
+ this.options.Router?.(this);
982
975
  }
983
976
  reset = () => {
984
977
  this.store.setState(s => Object.assign(s, getInitialRouterState()));
@@ -990,9 +983,6 @@
990
983
  if (!this.store.state.currentMatches.length) {
991
984
  this.load();
992
985
  }
993
- const unsubHistory = this.history.listen(() => {
994
- this.load(this.#parseLocation(this.store.state.latestLocation));
995
- });
996
986
  const visibilityChangeEvent = 'visibilitychange';
997
987
  const focusEvent = 'focus';
998
988
 
@@ -1005,7 +995,6 @@
1005
995
  window.addEventListener(focusEvent, this.#onFocus, false);
1006
996
  }
1007
997
  return () => {
1008
- unsubHistory();
1009
998
  if (window.removeEventListener) {
1010
999
  // Be sure to unsubscribe if a new handler is set
1011
1000
 
@@ -1017,13 +1006,20 @@
1017
1006
  return () => {};
1018
1007
  };
1019
1008
  update = opts => {
1020
- if (!this.store.state.latestLocation) {
1009
+ Object.assign(this.options, opts);
1010
+ if (!this.history || this.options.history && this.options.history !== this.history) {
1011
+ if (this.#unsubHistory) {
1012
+ this.#unsubHistory();
1013
+ }
1014
+ this.history = this.options.history ?? (isServer ? createMemoryHistory() : createBrowserHistory());
1021
1015
  this.store.setState(s => {
1022
1016
  s.latestLocation = this.#parseLocation();
1023
1017
  s.currentLocation = s.latestLocation;
1024
1018
  });
1019
+ this.#unsubHistory = this.history.listen(() => {
1020
+ this.load(this.#parseLocation(this.store.state.latestLocation));
1021
+ });
1025
1022
  }
1026
- Object.assign(this.options, opts);
1027
1023
  const {
1028
1024
  basepath,
1029
1025
  routeConfig
@@ -1248,7 +1244,7 @@
1248
1244
  const interpolatedPath = interpolatePath(foundRoute.path, params);
1249
1245
  const matchId = interpolatePath(foundRoute.id, params, true);
1250
1246
  const match = existingMatches.find(d => d.id === matchId) || this.store.state.matchCache[matchId]?.match || new RouteMatch(this, foundRoute, {
1251
- matchId,
1247
+ id: matchId,
1252
1248
  params,
1253
1249
  pathname: joinPaths([this.basepath, interpolatedPath])
1254
1250
  });
@@ -1320,10 +1316,11 @@
1320
1316
 
1321
1317
  // TODO: batch requests when possible
1322
1318
 
1323
- return this.options.fetchServerDataFn({
1319
+ const res = await this.options.fetchServerDataFn({
1324
1320
  router: this,
1325
1321
  routeMatch
1326
1322
  });
1323
+ return res;
1327
1324
  }
1328
1325
  };
1329
1326
  invalidateRoute = async opts => {
@@ -1514,7 +1511,7 @@
1514
1511
  state: {
1515
1512
  ...pick(this.store.state, ['latestLocation', 'currentLocation', 'status', 'lastUpdated']),
1516
1513
  currentMatches: this.store.state.currentMatches.map(match => ({
1517
- matchId: match.id,
1514
+ id: match.id,
1518
1515
  state: {
1519
1516
  ...pick(match.store.state, ['status', 'routeLoaderData', 'invalidAt', 'invalid'])
1520
1517
  }
@@ -1534,8 +1531,11 @@
1534
1531
  });
1535
1532
  currentMatches.forEach((match, index) => {
1536
1533
  const dehydratedMatch = dehydratedRouter.state.currentMatches[index];
1537
- invariant(dehydratedMatch && dehydratedMatch.matchId === match.id, 'Oh no! There was a hydration mismatch when attempting to rethis.store the state of the router! 😬');
1538
- Object.assign(match, dehydratedMatch);
1534
+ invariant(dehydratedMatch && dehydratedMatch.id === match.id, 'Oh no! There was a hydration mismatch when attempting to rethis.store the state of the router! 😬');
1535
+ match.store.setState(s => {
1536
+ Object.assign(s, dehydratedMatch.state);
1537
+ });
1538
+ match.setLoaderData(dehydratedMatch.state.routeLoaderData);
1539
1539
  });
1540
1540
  currentMatches.forEach(match => match.__validate());
1541
1541
  Object.assign(s, {
@@ -1681,7 +1681,9 @@
1681
1681
  id,
1682
1682
  ...next.state
1683
1683
  });
1684
- this.load(this.#parseLocation(this.store.state.latestLocation));
1684
+
1685
+ // this.load(this.#parseLocation(this.store.state.latestLocation))
1686
+
1685
1687
  return this.navigationPromise = new Promise(resolve => {
1686
1688
  const previousNavigationResolve = this.resolveNavigation;
1687
1689
  this.resolveNavigation = () => {
@@ -1723,7 +1725,7 @@
1723
1725
  });
1724
1726
  }
1725
1727
 
1726
- // createRouterAction is a constrained identify function that takes options: key, action, onSuccess, onError, onSettled, etc
1728
+ // RouterAction is a constrained identify function that takes options: key, action, onSuccess, onError, onSettled, etc
1727
1729
  function createAction(options) {
1728
1730
  const store = createStore({
1729
1731
  submissions: []