@tanstack/react-router 0.0.1-beta.56 → 0.0.1-beta.58

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.
@@ -88,6 +88,7 @@
88
88
  setState = updater => {
89
89
  const previous = this.state;
90
90
  this.state = this.options?.updateFn ? this.options.updateFn(previous)(updater) : updater(previous);
91
+ if (this.state === previous) return;
91
92
  this.queue.push(() => {
92
93
  this.listeners.forEach(listener => listener(this.state, previous));
93
94
  this.options?.onUpdate?.(this.state, previous);
@@ -564,62 +565,110 @@
564
565
  return out;
565
566
  }
566
567
 
568
+ const rootRouteId = '__root__';
567
569
  class Route {
568
- constructor(routeConfig, options, originalIndex, parent, router) {
569
- Object.assign(this, {
570
- ...routeConfig,
571
- originalIndex,
572
- options,
573
- getRouter: () => router,
574
- childRoutes: undefined,
575
- getParentRoute: () => parent
576
- });
577
- router.options.createRoute?.({
578
- router,
579
- route: this
580
- });
581
- }
582
- }
570
+ // Set up in this.init()
583
571
 
584
- const rootRouteId = '__root__';
585
- const createRouteConfig = (options = {}, children = [], isRoot = true, parentId, parentPath) => {
586
- if (isRoot) {
587
- options.path = rootRouteId;
588
- }
572
+ // customId!: TCustomId
589
573
 
590
- // Strip the root from parentIds
591
- if (parentId === rootRouteId) {
592
- parentId = '';
593
- }
594
- let path = isRoot ? rootRouteId : options.path;
574
+ // Optional
595
575
 
596
- // If the path is anything other than an index path, trim it up
597
- if (path && path !== '/') {
598
- path = trimPath(path);
599
- }
600
- const routeId = path || options.id;
601
- let id = joinPaths([parentId, routeId]);
602
- if (path === rootRouteId) {
603
- path = '/';
604
- }
605
- if (id !== rootRouteId) {
606
- id = joinPaths(['/', id]);
576
+ constructor(options) {
577
+ this.options = options || {};
578
+ this.isRoot = !options?.getParentRoute;
607
579
  }
608
- const fullPath = id === rootRouteId ? '/' : trimPathRight(joinPaths([parentPath, path]));
609
- return {
610
- id: id,
611
- routeId: routeId,
612
- path: path,
613
- fullPath: fullPath,
614
- options: options,
615
- children,
616
- addChildren: children => createRouteConfig(options, children, false, parentId, parentPath),
617
- createRoute: childOptions => createRouteConfig(childOptions, undefined, false, id, fullPath),
618
- generate: () => {
619
- invariant(false, `routeConfig.generate() is used by TanStack Router's file-based routing code generation and should not actually be called during runtime. `);
580
+ init = () => {
581
+ const allOptions = this.options;
582
+ const isRoot = !allOptions?.path && !allOptions?.id;
583
+ const parent = this.options?.getParentRoute?.();
584
+ if (isRoot) {
585
+ this.path = rootRouteId;
586
+ } else {
587
+ invariant(parent, `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`);
588
+ }
589
+ let path = isRoot ? rootRouteId : allOptions.path;
590
+
591
+ // If the path is anything other than an index path, trim it up
592
+ if (path && path !== '/') {
593
+ path = trimPath(path);
594
+ }
595
+ const customId = allOptions?.id || path;
596
+
597
+ // Strip the parentId prefix from the first level of children
598
+ let id = isRoot ? rootRouteId : joinPaths([parent.id === rootRouteId ? '' : parent.id, customId]);
599
+ if (path === rootRouteId) {
600
+ path = '/';
601
+ }
602
+ if (id !== rootRouteId) {
603
+ id = joinPaths(['/', id]);
620
604
  }
605
+ const fullPath = id === rootRouteId ? '/' : trimPathRight(joinPaths([parent.fullPath, path]));
606
+ this.id = id;
607
+ // this.customId = customId as TCustomId
608
+ this.fullPath = fullPath;
621
609
  };
622
- };
610
+ addChildren = children => {
611
+ this.children = children;
612
+ return this;
613
+ };
614
+
615
+ // generate: () => {
616
+ // invariant(
617
+ // false,
618
+ // `routeConfig.generate() is used by TanStack Router's file-based routing code generation and should not actually be called during runtime. `,
619
+ // )
620
+ // },
621
+ }
622
+
623
+ class RootRoute extends Route {
624
+ constructor(options) {
625
+ super(options);
626
+ }
627
+ }
628
+
629
+ // const rootRoute = new RootRoute({
630
+ // validateSearch: () => null as unknown as { root?: boolean },
631
+ // })
632
+
633
+ // const aRoute = new Route({
634
+ // getParentRoute: () => rootRoute,
635
+ // path: 'a',
636
+ // validateSearch: () => null as unknown as { a?: string },
637
+ // })
638
+
639
+ // const bRoute = new Route({
640
+ // getParentRoute: () => aRoute,
641
+ // path: 'b',
642
+ // })
643
+
644
+ // const rootIsRoot = rootRoute.isRoot
645
+ // // ^?
646
+ // const aIsRoot = aRoute.isRoot
647
+ // // ^?
648
+
649
+ // const rId = rootRoute.id
650
+ // // ^?
651
+ // const aId = aRoute.id
652
+ // // ^?
653
+ // const bId = bRoute.id
654
+ // // ^?
655
+
656
+ // const rPath = rootRoute.fullPath
657
+ // // ^?
658
+ // const aPath = aRoute.fullPath
659
+ // // ^?
660
+ // const bPath = bRoute.fullPath
661
+ // // ^?
662
+
663
+ // const rSearch = rootRoute.__types.fullSearchSchema
664
+ // // ^?
665
+ // const aSearch = aRoute.__types.fullSearchSchema
666
+ // // ^?
667
+ // const bSearch = bRoute.__types.fullSearchSchema
668
+ // // ^?
669
+
670
+ // const config = rootRoute.addChildren([aRoute.addChildren([bRoute])])
671
+ // // ^?
623
672
 
624
673
  //
625
674
 
@@ -651,14 +700,14 @@
651
700
  cancel = () => {
652
701
  this.abortController?.abort();
653
702
  };
654
- load = async () => {
703
+ load = async opts => {
655
704
  // If the match is invalid, errored or idle, trigger it to load
656
705
  if (this.store.state.status !== 'pending') {
657
- await this.fetch();
706
+ await this.fetch(opts);
658
707
  }
659
708
  };
660
709
  #latestId = '';
661
- fetch = async () => {
710
+ fetch = async opts => {
662
711
  this.__loadPromise = Promise.resolve().then(async () => {
663
712
  const loadId = '' + Date.now() + Math.random();
664
713
  this.#latestId = loadId;
@@ -693,7 +742,8 @@
693
742
  return this.route.options.onLoad({
694
743
  params: this.params,
695
744
  search: this.store.state.search,
696
- signal: this.abortController.signal
745
+ signal: this.abortController.signal,
746
+ preload: !!opts?.preload
697
747
  });
698
748
  }
699
749
  return;
@@ -907,12 +957,12 @@
907
957
  }
908
958
  const {
909
959
  basepath,
910
- routeConfig
960
+ routeTree
911
961
  } = this.options;
912
962
  this.basepath = `/${trimPath(basepath ?? '') ?? ''}`;
913
- if (routeConfig) {
963
+ if (routeTree) {
914
964
  this.routesById = {};
915
- this.routeTree = this.#buildRouteTree(routeConfig);
965
+ this.routeTree = this.#buildRouteTree(routeTree);
916
966
  }
917
967
  return this;
918
968
  };
@@ -1055,17 +1105,18 @@
1055
1105
  return matches;
1056
1106
  }
1057
1107
  const existingMatches = [...this.store.state.currentMatches, ...(this.store.state.pendingMatches ?? [])];
1058
- const recurse = async routes => {
1108
+ const findInRouteTree = async routes => {
1059
1109
  const parentMatch = last(matches);
1060
1110
  let params = parentMatch?.params ?? {};
1061
1111
  const filteredRoutes = this.options.filterRoutes?.(routes) ?? routes;
1062
- let foundRoutes = [];
1112
+ let matchingRoutes = [];
1063
1113
  const findMatchInRoutes = (parentRoutes, routes) => {
1064
1114
  routes.some(route => {
1065
- if (!route.path && route.childRoutes?.length) {
1066
- return findMatchInRoutes([...foundRoutes, route], route.childRoutes);
1115
+ const children = route.children;
1116
+ if (!route.path && children?.length) {
1117
+ return findMatchInRoutes([...matchingRoutes, route], children);
1067
1118
  }
1068
- const fuzzy = !!(route.path !== '/' || route.childRoutes?.length);
1119
+ const fuzzy = route.path === '/' ? false : !!children?.length;
1069
1120
  const matchParams = matchPathname(this.basepath, pathname, {
1070
1121
  to: route.fullPath,
1071
1122
  fuzzy,
@@ -1086,17 +1137,17 @@
1086
1137
  };
1087
1138
  }
1088
1139
  if (!!matchParams) {
1089
- foundRoutes = [...parentRoutes, route];
1140
+ matchingRoutes = [...parentRoutes, route];
1090
1141
  }
1091
- return !!foundRoutes.length;
1142
+ return !!matchingRoutes.length;
1092
1143
  });
1093
- return !!foundRoutes.length;
1144
+ return !!matchingRoutes.length;
1094
1145
  };
1095
1146
  findMatchInRoutes([], filteredRoutes);
1096
- if (!foundRoutes.length) {
1147
+ if (!matchingRoutes.length) {
1097
1148
  return;
1098
1149
  }
1099
- foundRoutes.forEach(foundRoute => {
1150
+ matchingRoutes.forEach(foundRoute => {
1100
1151
  const interpolatedPath = interpolatePath(foundRoute.path, params);
1101
1152
  const matchId = interpolatePath(foundRoute.id, params, true);
1102
1153
  const match = existingMatches.find(d => d.id === matchId) ||
@@ -1108,12 +1159,13 @@
1108
1159
  });
1109
1160
  matches.push(match);
1110
1161
  });
1111
- const foundRoute = last(foundRoutes);
1112
- if (foundRoute.childRoutes?.length) {
1113
- recurse(foundRoute.childRoutes);
1162
+ const foundRoute = last(matchingRoutes);
1163
+ const foundChildren = foundRoute.children;
1164
+ if (foundChildren?.length) {
1165
+ findInRouteTree(foundChildren);
1114
1166
  }
1115
1167
  };
1116
- recurse([this.routeTree]);
1168
+ findInRouteTree([this.routeTree]);
1117
1169
  linkMatches(matches);
1118
1170
  return matches;
1119
1171
  };
@@ -1144,7 +1196,9 @@
1144
1196
  if (search.__data?.matchId && search.__data.matchId !== match.id) {
1145
1197
  return;
1146
1198
  }
1147
- match.load();
1199
+ match.load({
1200
+ preload: loaderOpts?.preload
1201
+ });
1148
1202
  if (match.store.state.status !== 'success' && match.__loadPromise) {
1149
1203
  // Wait for the first sign of activity from the match
1150
1204
  await match.__loadPromise;
@@ -1358,11 +1412,12 @@
1358
1412
  };
1359
1413
  });
1360
1414
  };
1361
- #buildRouteTree = rootRouteConfig => {
1362
- const recurseRoutes = (routeConfigs, parent) => {
1363
- return routeConfigs.map((routeConfig, i) => {
1364
- const routeOptions = routeConfig.options;
1365
- const route = new Route(routeConfig, routeOptions, i, parent, this);
1415
+ #buildRouteTree = routeTree => {
1416
+ const recurseRoutes = routes => {
1417
+ routes.forEach((route, i) => {
1418
+ route.init();
1419
+ route.originalIndex = i;
1420
+ route.router = this;
1366
1421
  const existingRoute = this.routesById[route.id];
1367
1422
  if (existingRoute) {
1368
1423
  {
@@ -1371,13 +1426,12 @@
1371
1426
  throw new Error();
1372
1427
  }
1373
1428
  this.routesById[route.id] = route;
1374
- const children = routeConfig.children;
1375
- route.childRoutes = children.length ? recurseRoutes(children, route) : undefined;
1376
- return route;
1429
+ const children = route.children;
1430
+ if (children?.length) recurseRoutes(children);
1377
1431
  });
1378
1432
  };
1379
- const routes = recurseRoutes([rootRouteConfig]);
1380
- return routes[0];
1433
+ recurseRoutes([routeTree]);
1434
+ return routeTree;
1381
1435
  };
1382
1436
  #parseLocation = previousLocation => {
1383
1437
  let {
@@ -1838,6 +1892,11 @@
1838
1892
  match: match
1839
1893
  }))));
1840
1894
  }
1895
+
1896
+ // This is the messiest thing ever... I'm either seriously tired (likely) or
1897
+ // there has to be a better way to reset error boundaries when the
1898
+ // router's location key changes.
1899
+
1841
1900
  class CatchBoundary extends React__namespace.Component {
1842
1901
  state = {
1843
1902
  error: false,
@@ -1858,10 +1917,6 @@
1858
1917
  }));
1859
1918
  }
1860
1919
  }
1861
-
1862
- // This is the messiest thing ever... I'm either seriously tired (likely) or
1863
- // there has to be a better way to reset error boundaries when the
1864
- // router's location key changes.
1865
1920
  function CatchBoundaryInner(props) {
1866
1921
  const [activeErrorState, setActiveErrorState] = React__namespace.useState(props.errorState);
1867
1922
  const router = useRouter();
@@ -1945,6 +2000,7 @@
1945
2000
  exports.MatchRoute = MatchRoute;
1946
2001
  exports.Outlet = Outlet;
1947
2002
  exports.ReactRouter = ReactRouter;
2003
+ exports.RootRoute = RootRoute;
1948
2004
  exports.Route = Route;
1949
2005
  exports.RouteMatch = RouteMatch;
1950
2006
  exports.Router = Router;
@@ -1953,7 +2009,6 @@
1953
2009
  exports.createBrowserHistory = createBrowserHistory;
1954
2010
  exports.createHashHistory = createHashHistory;
1955
2011
  exports.createMemoryHistory = createMemoryHistory;
1956
- exports.createRouteConfig = createRouteConfig;
1957
2012
  exports.decode = decode;
1958
2013
  exports.defaultFetchServerDataFn = defaultFetchServerDataFn;
1959
2014
  exports.defaultParseSearch = defaultParseSearch;