@tanstack/router-core 0.0.1-beta.2 → 0.0.1-beta.23

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 (35) hide show
  1. package/build/cjs/packages/router-core/src/index.js +1 -1
  2. package/build/cjs/packages/router-core/src/path.js +1 -4
  3. package/build/cjs/packages/router-core/src/path.js.map +1 -1
  4. package/build/cjs/packages/router-core/src/qss.js +1 -0
  5. package/build/cjs/packages/router-core/src/qss.js.map +1 -1
  6. package/build/cjs/packages/router-core/src/route.js +9 -23
  7. package/build/cjs/packages/router-core/src/route.js.map +1 -1
  8. package/build/cjs/packages/router-core/src/routeConfig.js.map +1 -1
  9. package/build/cjs/packages/router-core/src/routeMatch.js +75 -121
  10. package/build/cjs/packages/router-core/src/routeMatch.js.map +1 -1
  11. package/build/cjs/packages/router-core/src/router.js +183 -89
  12. package/build/cjs/packages/router-core/src/router.js.map +1 -1
  13. package/build/cjs/packages/router-core/src/utils.js +7 -6
  14. package/build/cjs/packages/router-core/src/utils.js.map +1 -1
  15. package/build/esm/index.js +271 -237
  16. package/build/esm/index.js.map +1 -1
  17. package/build/stats-html.html +1 -1
  18. package/build/stats-react.json +139 -152
  19. package/build/types/index.d.ts +199 -191
  20. package/build/umd/index.development.js +271 -237
  21. package/build/umd/index.development.js.map +1 -1
  22. package/build/umd/index.production.js +1 -1
  23. package/build/umd/index.production.js.map +1 -1
  24. package/package.json +2 -1
  25. package/src/frameworks.ts +1 -2
  26. package/src/index.ts +0 -1
  27. package/src/link.ts +3 -1
  28. package/src/path.ts +0 -4
  29. package/src/qss.ts +1 -0
  30. package/src/route.ts +10 -26
  31. package/src/routeConfig.ts +30 -21
  32. package/src/routeInfo.ts +13 -3
  33. package/src/routeMatch.ts +94 -156
  34. package/src/router.ts +269 -109
  35. package/src/utils.ts +12 -5
@@ -832,12 +832,6 @@
832
832
  throw new Error(value);
833
833
  }
834
834
 
835
- // type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
836
- // k: infer I,
837
- // ) => any
838
- // ? I
839
- // : never
840
-
841
835
  /**
842
836
  * This function returns `a` if `b` is deeply equal.
843
837
  * If not, it will replace any deeply equal children of `b` with those of `a`.
@@ -930,6 +924,12 @@
930
924
 
931
925
  return updater;
932
926
  }
927
+ function pick(parent, keys) {
928
+ return keys.reduce((obj, key) => {
929
+ obj[key] = parent[key];
930
+ return obj;
931
+ }, {});
932
+ }
933
933
 
934
934
  function joinPaths(paths) {
935
935
  return cleanPath(paths.filter(Boolean).join('/'));
@@ -1053,10 +1053,7 @@
1053
1053
 
1054
1054
  if (matchLocation.to && !pathParams) {
1055
1055
  return;
1056
- } // if (matchLocation.search && !searchMatched) {
1057
- // return
1058
- // }
1059
-
1056
+ }
1060
1057
 
1061
1058
  return pathParams != null ? pathParams : {};
1062
1059
  }
@@ -1156,6 +1153,7 @@
1156
1153
  var str = decodeURIComponent(mix);
1157
1154
  if (str === 'false') return false;
1158
1155
  if (str === 'true') return true;
1156
+ if (str.charAt(0) === '0') return str;
1159
1157
  return +str * 0 === 0 ? +str : str;
1160
1158
  }
1161
1159
 
@@ -1206,7 +1204,7 @@
1206
1204
 
1207
1205
  const action = router.state.actions[id] || (() => {
1208
1206
  router.state.actions[id] = {
1209
- pending: [],
1207
+ submissions: [],
1210
1208
  submit: async (submission, actionOpts) => {
1211
1209
  var _actionOpts$invalidat;
1212
1210
 
@@ -1215,18 +1213,20 @@
1215
1213
  }
1216
1214
 
1217
1215
  const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
1216
+
1217
+ if (!(actionOpts != null && actionOpts.multi)) {
1218
+ action.submissions = action.submissions.filter(d => d.isMulti);
1219
+ }
1220
+
1218
1221
  const actionState = {
1219
1222
  submittedAt: Date.now(),
1220
1223
  status: 'pending',
1221
- submission
1224
+ submission,
1225
+ isMulti: !!(actionOpts != null && actionOpts.multi)
1222
1226
  };
1223
1227
  action.current = actionState;
1224
1228
  action.latest = actionState;
1225
- action.pending.push(actionState);
1226
- router.state = _extends({}, router.state, {
1227
- currentAction: actionState,
1228
- latestAction: actionState
1229
- });
1229
+ action.submissions.push(actionState);
1230
1230
  router.notify();
1231
1231
 
1232
1232
  try {
@@ -1248,11 +1248,6 @@
1248
1248
  actionState.error = err;
1249
1249
  actionState.status = 'error';
1250
1250
  } finally {
1251
- action.pending = action.pending.filter(d => d !== actionState);
1252
- router.removeActionQueue.push({
1253
- action,
1254
- actionState
1255
- });
1256
1251
  router.notify();
1257
1252
  }
1258
1253
  }
@@ -1327,15 +1322,6 @@
1327
1322
  });
1328
1323
  return route;
1329
1324
  }
1330
- function cascadeLoaderData(matches) {
1331
- matches.forEach((match, index) => {
1332
- const parent = matches[index - 1];
1333
-
1334
- if (parent) {
1335
- match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
1336
- }
1337
- });
1338
- }
1339
1325
 
1340
1326
  const rootRouteId = '__root__';
1341
1327
  const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId, parentPath) {
@@ -1387,7 +1373,7 @@
1387
1373
  };
1388
1374
  };
1389
1375
 
1390
- const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1376
+ const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
1391
1377
  function createRouteMatch(router, route, opts) {
1392
1378
  const routeMatch = _extends({}, route, opts, {
1393
1379
  router,
@@ -1397,10 +1383,10 @@
1397
1383
  status: 'idle',
1398
1384
  routeLoaderData: {},
1399
1385
  loaderData: {},
1400
- isPending: false,
1401
1386
  isFetching: false,
1402
1387
  isInvalid: false,
1403
1388
  invalidAt: Infinity,
1389
+ // pendingActions: [],
1404
1390
  getIsInvalid: () => {
1405
1391
  const now = Date.now();
1406
1392
  return routeMatch.isInvalid || routeMatch.invalidAt < now;
@@ -1414,43 +1400,6 @@
1414
1400
 
1415
1401
  routeMatch.router.notify();
1416
1402
  },
1417
- startPending: () => {
1418
- var _routeMatch$options$p, _routeMatch$options$p2;
1419
-
1420
- const pendingMs = (_routeMatch$options$p = routeMatch.options.pendingMs) != null ? _routeMatch$options$p : router.options.defaultPendingMs;
1421
- const pendingMinMs = (_routeMatch$options$p2 = routeMatch.options.pendingMinMs) != null ? _routeMatch$options$p2 : router.options.defaultPendingMinMs;
1422
-
1423
- if (routeMatch.__.pendingTimeout || routeMatch.status !== 'loading' || typeof pendingMs === 'undefined') {
1424
- return;
1425
- }
1426
-
1427
- routeMatch.__.pendingTimeout = setTimeout(() => {
1428
- routeMatch.isPending = true;
1429
-
1430
- routeMatch.__.resolve();
1431
-
1432
- if (typeof pendingMinMs !== 'undefined') {
1433
- routeMatch.__.pendingMinPromise = new Promise(r => routeMatch.__.pendingMinTimeout = setTimeout(r, pendingMinMs));
1434
- }
1435
- }, pendingMs);
1436
- },
1437
- cancelPending: () => {
1438
- routeMatch.isPending = false;
1439
- clearTimeout(routeMatch.__.pendingTimeout);
1440
- clearTimeout(routeMatch.__.pendingMinTimeout);
1441
- delete routeMatch.__.pendingMinPromise;
1442
- },
1443
- // setParentMatch: (parentMatch?: RouteMatch) => {
1444
- // routeMatch.parentMatch = parentMatch
1445
- // },
1446
- // addChildMatch: (childMatch: RouteMatch) => {
1447
- // if (
1448
- // routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
1449
- // ) {
1450
- // return
1451
- // }
1452
- // routeMatch.childMatches.push(childMatch)
1453
- // },
1454
1403
  validate: () => {
1455
1404
  var _routeMatch$parentMat, _routeMatch$parentMat2;
1456
1405
 
@@ -1458,9 +1407,11 @@
1458
1407
  const parentSearch = (_routeMatch$parentMat = (_routeMatch$parentMat2 = routeMatch.parentMatch) == null ? void 0 : _routeMatch$parentMat2.search) != null ? _routeMatch$parentMat : router.location.search;
1459
1408
 
1460
1409
  try {
1410
+ var _validator;
1411
+
1461
1412
  const prevSearch = routeMatch.routeSearch;
1462
1413
  const validator = typeof routeMatch.options.validateSearch === 'object' ? routeMatch.options.validateSearch.parse : routeMatch.options.validateSearch;
1463
- let nextSearch = replaceEqualDeep(prevSearch, validator == null ? void 0 : validator(parentSearch)); // Invalidate route matches when search param stability changes
1414
+ let nextSearch = replaceEqualDeep(prevSearch, (_validator = validator == null ? void 0 : validator(parentSearch)) != null ? _validator : {}); // Invalidate route matches when search param stability changes
1464
1415
 
1465
1416
  if (prevSearch !== nextSearch) {
1466
1417
  routeMatch.isInvalid = true;
@@ -1468,6 +1419,13 @@
1468
1419
 
1469
1420
  routeMatch.routeSearch = nextSearch;
1470
1421
  routeMatch.search = replaceEqualDeep(parentSearch, _extends({}, parentSearch, nextSearch));
1422
+ componentTypes.map(async type => {
1423
+ const component = routeMatch.options[type];
1424
+
1425
+ if (typeof routeMatch.__[type] !== 'function') {
1426
+ routeMatch.__[type] = component;
1427
+ }
1428
+ });
1471
1429
  } catch (err) {
1472
1430
  console.error(err);
1473
1431
  const error = new Error('Invalid search params found', {
@@ -1485,14 +1443,16 @@
1485
1443
  var _routeMatch$__$abortC;
1486
1444
 
1487
1445
  (_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
1488
-
1489
- routeMatch.__.cancelPending();
1490
1446
  },
1491
1447
  invalidate: () => {
1492
1448
  routeMatch.isInvalid = true;
1493
1449
  },
1494
1450
  hasLoaders: () => {
1495
- return !!(route.options.loader || elementTypes.some(d => typeof route.options[d] === 'function'));
1451
+ return !!(route.options.loader || componentTypes.some(d => {
1452
+ var _route$options$d;
1453
+
1454
+ return (_route$options$d = route.options[d]) == null ? void 0 : _route$options$d.preload;
1455
+ }));
1496
1456
  },
1497
1457
  load: async loaderOpts => {
1498
1458
  const now = Date.now();
@@ -1513,17 +1473,25 @@
1513
1473
 
1514
1474
  if (routeMatch.status === 'success' && routeMatch.getIsInvalid() || routeMatch.status === 'error' || routeMatch.status === 'idle') {
1515
1475
  const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
1516
- routeMatch.fetch({
1476
+ await routeMatch.fetch({
1517
1477
  maxAge
1518
1478
  });
1519
1479
  }
1520
1480
  },
1521
1481
  fetch: async opts => {
1522
- const id = '' + Date.now() + Math.random();
1523
- routeMatch.__.latestId = id; // If the match was in an error state, set it
1482
+ const loadId = '' + Date.now() + Math.random();
1483
+ routeMatch.__.latestId = loadId;
1484
+
1485
+ const checkLatest = async () => {
1486
+ if (loadId !== routeMatch.__.latestId) {
1487
+ // warning(true, 'Data loader is out of date!')
1488
+ return new Promise(() => {});
1489
+ }
1490
+ }; // If the match was in an error state, set it
1524
1491
  // to a loading state again. Otherwise, keep it
1525
1492
  // as loading or resolved
1526
1493
 
1494
+
1527
1495
  if (routeMatch.status === 'idle') {
1528
1496
  routeMatch.status = 'loading';
1529
1497
  } // We started loading the route, so it's no longer invalid
@@ -1536,94 +1504,66 @@
1536
1504
  routeMatch.isFetching = true;
1537
1505
  routeMatch.__.resolve = resolve;
1538
1506
 
1539
- const loaderPromise = (async () => {
1540
- // Load the elements and data in parallel
1541
- routeMatch.__.elementsPromise = (async () => {
1542
- // then run all element and data loaders in parallel
1543
- // For each element type, potentially load it asynchronously
1544
- await Promise.all(elementTypes.map(async type => {
1545
- const routeElement = routeMatch.options[type];
1546
-
1547
- if (routeMatch.__[type]) {
1548
- return;
1549
- }
1550
-
1551
- routeMatch.__[type] = await router.options.createElement(routeElement);
1552
- }));
1553
- })();
1554
-
1555
- routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1556
- try {
1557
- var _ref, _ref2, _opts$maxAge;
1507
+ routeMatch.__.componentsPromise = (async () => {
1508
+ // then run all component and data loaders in parallel
1509
+ // For each component type, potentially load it asynchronously
1510
+ await Promise.all(componentTypes.map(async type => {
1511
+ var _routeMatch$__$type;
1558
1512
 
1559
- if (routeMatch.options.loader) {
1560
- const data = await routeMatch.options.loader({
1561
- params: routeMatch.params,
1562
- search: routeMatch.routeSearch,
1563
- signal: routeMatch.__.abortController.signal
1564
- });
1513
+ const component = routeMatch.options[type];
1565
1514
 
1566
- if (id !== routeMatch.__.latestId) {
1567
- return routeMatch.__.loaderPromise;
1568
- }
1569
-
1570
- routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1571
- }
1572
-
1573
- routeMatch.error = undefined;
1574
- routeMatch.status = 'success';
1575
- routeMatch.updatedAt = Date.now();
1576
- routeMatch.invalidAt = routeMatch.updatedAt + ((_ref = (_ref2 = (_opts$maxAge = opts == null ? void 0 : opts.maxAge) != null ? _opts$maxAge : routeMatch.options.loaderMaxAge) != null ? _ref2 : router.options.defaultLoaderMaxAge) != null ? _ref : 0);
1577
- } catch (err) {
1578
- if (id !== routeMatch.__.latestId) {
1579
- return routeMatch.__.loaderPromise;
1580
- }
1581
-
1582
- {
1583
- console.error(err);
1584
- }
1585
-
1586
- routeMatch.error = err;
1587
- routeMatch.status = 'error';
1588
- routeMatch.updatedAt = Date.now();
1515
+ if ((_routeMatch$__$type = routeMatch.__[type]) != null && _routeMatch$__$type.preload) {
1516
+ routeMatch.__[type] = await router.options.loadComponent(component);
1589
1517
  }
1590
- });
1518
+ }));
1519
+ })();
1591
1520
 
1521
+ routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1592
1522
  try {
1593
- await Promise.all([routeMatch.__.elementsPromise, routeMatch.__.dataPromise]);
1594
-
1595
- if (id !== routeMatch.__.latestId) {
1596
- return routeMatch.__.loaderPromise;
1597
- }
1523
+ var _ref, _ref2, _opts$maxAge;
1598
1524
 
1599
- if (routeMatch.__.pendingMinPromise) {
1600
- await routeMatch.__.pendingMinPromise;
1601
- delete routeMatch.__.pendingMinPromise;
1602
- }
1603
- } finally {
1604
- if (id !== routeMatch.__.latestId) {
1605
- return routeMatch.__.loaderPromise;
1525
+ if (routeMatch.options.loader) {
1526
+ const data = await router.loadMatchData(routeMatch);
1527
+ await checkLatest();
1528
+ routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1606
1529
  }
1607
1530
 
1608
- routeMatch.__.cancelPending();
1531
+ routeMatch.error = undefined;
1532
+ routeMatch.status = 'success';
1533
+ routeMatch.updatedAt = Date.now();
1534
+ routeMatch.invalidAt = routeMatch.updatedAt + ((_ref = (_ref2 = (_opts$maxAge = opts == null ? void 0 : opts.maxAge) != null ? _opts$maxAge : routeMatch.options.loaderMaxAge) != null ? _ref2 : router.options.defaultLoaderMaxAge) != null ? _ref : 0);
1535
+ return routeMatch.routeLoaderData;
1536
+ } catch (err) {
1537
+ await checkLatest();
1609
1538
 
1610
- routeMatch.isPending = false;
1611
- routeMatch.isFetching = false;
1539
+ {
1540
+ console.error(err);
1541
+ }
1612
1542
 
1613
- routeMatch.__.notify();
1543
+ routeMatch.error = err;
1544
+ routeMatch.status = 'error';
1545
+ routeMatch.updatedAt = Date.now();
1546
+ throw err;
1614
1547
  }
1615
- })();
1548
+ });
1616
1549
 
1617
- routeMatch.__.loaderPromise = loaderPromise;
1618
- await loaderPromise;
1550
+ const after = async () => {
1551
+ await checkLatest();
1552
+ routeMatch.isFetching = false;
1553
+ delete routeMatch.__.loadPromise;
1619
1554
 
1620
- if (id !== routeMatch.__.latestId) {
1621
- return routeMatch.__.loaderPromise;
1622
- }
1555
+ routeMatch.__.notify();
1556
+ };
1623
1557
 
1624
- delete routeMatch.__.loaderPromise;
1558
+ try {
1559
+ await Promise.all([routeMatch.__.componentsPromise, routeMatch.__.dataPromise.catch(() => {})]);
1560
+ after();
1561
+ } catch (_unused) {
1562
+ after();
1563
+ }
1625
1564
  });
1626
- return await routeMatch.__.loadPromise;
1565
+ await routeMatch.__.loadPromise;
1566
+ await checkLatest();
1627
1567
  }
1628
1568
  });
1629
1569
 
@@ -1684,9 +1624,22 @@
1684
1624
 
1685
1625
  var _window$document;
1686
1626
  // Detect if we're in the DOM
1687
- const isServer = Boolean(typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement)); // This is the default history object if none is defined
1627
+ const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement); // This is the default history object if none is defined
1688
1628
 
1689
- const createDefaultHistory = () => !isServer ? createBrowserHistory() : createMemoryHistory();
1629
+ const createDefaultHistory = () => isServer ? createMemoryHistory() : createBrowserHistory();
1630
+
1631
+ function getInitialRouterState() {
1632
+ return {
1633
+ status: 'idle',
1634
+ location: null,
1635
+ matches: [],
1636
+ actions: {},
1637
+ loaders: {},
1638
+ lastUpdated: Date.now(),
1639
+ isFetching: false,
1640
+ isPreloading: false
1641
+ };
1642
+ }
1690
1643
 
1691
1644
  function createRouter(userOptions) {
1692
1645
  var _userOptions$stringif, _userOptions$parseSea;
@@ -1704,30 +1657,25 @@
1704
1657
  });
1705
1658
 
1706
1659
  let router = {
1660
+ types: undefined,
1661
+ // public api
1707
1662
  history,
1708
1663
  options: originalOptions,
1709
1664
  listeners: [],
1710
- removeActionQueue: [],
1711
1665
  // Resolved after construction
1666
+ context: {},
1712
1667
  basepath: '',
1713
1668
  routeTree: undefined,
1714
1669
  routesById: {},
1715
1670
  location: undefined,
1716
- allRouteInfo: undefined,
1717
1671
  //
1718
1672
  navigationPromise: Promise.resolve(),
1719
1673
  resolveNavigation: () => {},
1720
1674
  matchCache: {},
1721
- state: {
1722
- status: 'idle',
1723
- location: null,
1724
- matches: [],
1725
- actions: {},
1726
- loaders: {},
1727
- loaderData: {},
1728
- lastUpdated: Date.now(),
1729
- isFetching: false,
1730
- isPreloading: false
1675
+ state: getInitialRouterState(),
1676
+ reset: () => {
1677
+ router.state = getInitialRouterState();
1678
+ router.notify();
1731
1679
  },
1732
1680
  startedLoadingAt: Date.now(),
1733
1681
  subscribe: listener => {
@@ -1740,13 +1688,39 @@
1740
1688
  return router.routesById[id];
1741
1689
  },
1742
1690
  notify: () => {
1743
- router.state = _extends({}, router.state, {
1744
- isFetching: router.state.status === 'loading' || router.state.matches.some(d => d.isFetching),
1745
- isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
1746
- });
1691
+ const isFetching = router.state.status === 'loading' || router.state.matches.some(d => d.isFetching);
1692
+ const isPreloading = Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId));
1693
+
1694
+ if (router.state.isFetching !== isFetching || router.state.isPreloading !== isPreloading) {
1695
+ router.state = _extends({}, router.state, {
1696
+ isFetching,
1697
+ isPreloading
1698
+ });
1699
+ }
1700
+
1747
1701
  cascadeLoaderData(router.state.matches);
1748
1702
  router.listeners.forEach(listener => listener(router));
1749
1703
  },
1704
+ dehydrateState: () => {
1705
+ return _extends({}, pick(router.state, ['status', 'location', 'lastUpdated']), {
1706
+ matches: router.state.matches.map(match => pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
1707
+ });
1708
+ },
1709
+ hydrateState: dehydratedState => {
1710
+ // Match the routes
1711
+ const matches = router.matchRoutes(router.location.pathname, {
1712
+ strictParseParams: true
1713
+ });
1714
+ matches.forEach((match, index) => {
1715
+ const dehydratedMatch = dehydratedState.matches[index];
1716
+ invariant(dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
1717
+ Object.assign(match, dehydratedMatch);
1718
+ });
1719
+ matches.forEach(match => match.__.validate());
1720
+ router.state = _extends({}, router.state, dehydratedState, {
1721
+ matches
1722
+ });
1723
+ },
1750
1724
  mount: () => {
1751
1725
  const next = router.__.buildLocation({
1752
1726
  to: '.',
@@ -1758,12 +1732,14 @@
1758
1732
 
1759
1733
  if (next.href !== router.location.href) {
1760
1734
  router.__.commitLocation(next, true);
1761
- } else {
1762
- router.loadLocation();
1763
1735
  }
1764
1736
 
1765
- const unsub = history.listen(event => {
1766
- router.loadLocation(router.__.parseLocation(event.location, router.location));
1737
+ if (!router.state.matches.length) {
1738
+ router.load();
1739
+ }
1740
+
1741
+ const unsub = router.history.listen(event => {
1742
+ router.load(router.__.parseLocation(event.location, router.location));
1767
1743
  }); // addEventListener does not exist in React Native, but window does
1768
1744
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1769
1745
 
@@ -1774,16 +1750,30 @@
1774
1750
  }
1775
1751
 
1776
1752
  return () => {
1777
- unsub(); // Be sure to unsubscribe if a new handler is set
1753
+ unsub();
1778
1754
 
1779
- window.removeEventListener('visibilitychange', router.onFocus);
1780
- window.removeEventListener('focus', router.onFocus);
1755
+ if (!isServer && window.removeEventListener) {
1756
+ // Be sure to unsubscribe if a new handler is set
1757
+ window.removeEventListener('visibilitychange', router.onFocus);
1758
+ window.removeEventListener('focus', router.onFocus);
1759
+ }
1781
1760
  };
1782
1761
  },
1783
1762
  onFocus: () => {
1784
- router.loadLocation();
1763
+ router.load();
1785
1764
  },
1786
1765
  update: opts => {
1766
+ const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
1767
+
1768
+ if (!router.location || newHistory) {
1769
+ if (opts != null && opts.history) {
1770
+ router.history = opts.history;
1771
+ }
1772
+
1773
+ router.location = router.__.parseLocation(router.history.location);
1774
+ router.state.location = router.location;
1775
+ }
1776
+
1787
1777
  Object.assign(router.options, opts);
1788
1778
  const {
1789
1779
  basepath,
@@ -1804,49 +1794,53 @@
1804
1794
  match.cancel();
1805
1795
  });
1806
1796
  },
1807
- loadLocation: async next => {
1797
+ load: async next => {
1808
1798
  const id = Math.random();
1809
1799
  router.startedLoadingAt = id;
1810
1800
 
1811
1801
  if (next) {
1812
1802
  // Ingest the new location
1813
1803
  router.location = next;
1814
- } // Clear out old actions
1804
+ } // Cancel any pending matches
1815
1805
 
1816
1806
 
1817
- router.removeActionQueue.forEach(_ref => {
1818
- let {
1819
- action,
1820
- actionState
1821
- } = _ref;
1807
+ router.cancelMatches(); // Match the routes
1822
1808
 
1823
- if (router.state.currentAction === actionState) {
1824
- router.state.currentAction = undefined;
1825
- }
1809
+ const matches = router.matchRoutes(router.location.pathname, {
1810
+ strictParseParams: true
1811
+ }); // Check if each match middleware to see if the route can be accessed
1826
1812
 
1827
- if (action.current === actionState) {
1828
- action.current = undefined;
1813
+ try {
1814
+ await Promise.all(matches.map(match => match.options.beforeLoad == null ? void 0 : match.options.beforeLoad({
1815
+ context: router.context
1816
+ })));
1817
+ } catch (err) {
1818
+ if (err != null && err.then) {
1819
+ await new Promise(() => {});
1829
1820
  }
1830
- });
1831
- router.removeActionQueue = []; // Cancel any pending matches
1832
1821
 
1833
- router.cancelMatches(); // Match the routes
1822
+ throw err;
1823
+ }
1834
1824
 
1835
- const matches = router.matchRoutes(location.pathname, {
1836
- strictParseParams: true
1837
- });
1838
- router.state = _extends({}, router.state, {
1839
- pending: {
1825
+ if (typeof document !== 'undefined') {
1826
+ router.state = _extends({}, router.state, {
1827
+ pending: {
1828
+ matches: matches,
1829
+ location: router.location
1830
+ },
1831
+ status: 'loading'
1832
+ });
1833
+ } else {
1834
+ router.state = _extends({}, router.state, {
1840
1835
  matches: matches,
1841
- location: router.location
1842
- },
1843
- status: 'loading'
1844
- });
1836
+ location: router.location,
1837
+ status: 'loading'
1838
+ });
1839
+ }
1840
+
1845
1841
  router.notify(); // Load the matches
1846
1842
 
1847
- await router.loadMatches(matches, {
1848
- withPending: true
1849
- });
1843
+ await router.loadMatches(matches);
1850
1844
 
1851
1845
  if (router.startedLoadingAt !== id) {
1852
1846
  // Ignore side-effects of match loading
@@ -1863,9 +1857,12 @@
1863
1857
  exiting.push(d);
1864
1858
  }
1865
1859
  });
1860
+ const entering = matches.filter(d => {
1861
+ return !previousMatches.find(dd => dd.matchId === d.matchId);
1862
+ });
1866
1863
  const now = Date.now();
1867
1864
  exiting.forEach(d => {
1868
- var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
1865
+ var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
1869
1866
 
1870
1867
  d.__.onExit == null ? void 0 : d.__.onExit({
1871
1868
  params: d.params,
@@ -1877,7 +1874,7 @@
1877
1874
  d.error = undefined;
1878
1875
  }
1879
1876
 
1880
- const gc = Math.max((_ref2 = (_d$options$loaderGcMa = d.options.loaderGcMaxAge) != null ? _d$options$loaderGcMa : router.options.defaultLoaderGcMaxAge) != null ? _ref2 : 0, (_ref3 = (_d$options$loaderMaxA = d.options.loaderMaxAge) != null ? _d$options$loaderMaxA : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0);
1877
+ 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);
1881
1878
 
1882
1879
  if (gc > 0) {
1883
1880
  router.matchCache[d.matchId] = {
@@ -1892,27 +1889,26 @@
1892
1889
  search: d.routeSearch
1893
1890
  });
1894
1891
  });
1895
- const entering = matches.filter(d => {
1896
- return !previousMatches.find(dd => dd.matchId === d.matchId);
1897
- });
1898
1892
  entering.forEach(d => {
1899
- d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
1893
+ d.__.onExit = d.options.onLoaded == null ? void 0 : d.options.onLoaded({
1900
1894
  params: d.params,
1901
1895
  search: d.search
1902
1896
  });
1903
1897
  delete router.matchCache[d.matchId];
1904
1898
  });
1905
1899
 
1906
- if (matches.some(d => d.status === 'loading')) {
1907
- router.notify();
1908
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
1909
- }
1910
-
1911
1900
  if (router.startedLoadingAt !== id) {
1912
1901
  // Ignore side-effects of match loading
1913
1902
  return;
1914
1903
  }
1915
1904
 
1905
+ matches.forEach(match => {
1906
+ // Clear actions
1907
+ if (match.action) {
1908
+ match.action.current = undefined;
1909
+ match.action.submissions = [];
1910
+ }
1911
+ });
1916
1912
  router.state = _extends({}, router.state, {
1917
1913
  location: router.location,
1918
1914
  matches,
@@ -1953,7 +1949,7 @@
1953
1949
  return matches;
1954
1950
  },
1955
1951
  preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
1956
- var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
1952
+ var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
1957
1953
 
1958
1954
  if (navigateOpts === void 0) {
1959
1955
  navigateOpts = router.location;
@@ -1965,8 +1961,8 @@
1965
1961
  });
1966
1962
  await router.loadMatches(matches, {
1967
1963
  preload: true,
1968
- maxAge: (_ref4 = (_ref5 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref5 : router.options.defaultLoaderMaxAge) != null ? _ref4 : 0,
1969
- gcMaxAge: (_ref6 = (_ref7 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0
1964
+ maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
1965
+ gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
1970
1966
  });
1971
1967
  return matches;
1972
1968
  },
@@ -2042,6 +2038,7 @@
2042
2038
  const interpolatedPath = interpolatePath(foundRoute.routePath, params);
2043
2039
  const matchId = interpolatePath(foundRoute.routeId, params, true);
2044
2040
  const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || createRouteMatch(router, foundRoute, {
2041
+ parentMatch,
2045
2042
  matchId,
2046
2043
  params,
2047
2044
  pathname: joinPaths([pathname, interpolatedPath])
@@ -2065,18 +2062,51 @@
2065
2062
  match.__.validate();
2066
2063
 
2067
2064
  match.load(loaderOpts);
2065
+ const search = match.search;
2068
2066
 
2069
- if (match.status === 'loading') {
2070
- // If requested, start the pending timers
2071
- if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
2072
- // This might be completion, error, or a pending state
2067
+ if (search.__data && search.__data.matchId !== match.matchId) {
2068
+ return;
2069
+ }
2073
2070
 
2071
+ if (match.__.loadPromise) {
2072
+ // Wait for the first sign of activity from the match
2074
2073
  await match.__.loadPromise;
2075
2074
  }
2076
2075
  });
2077
2076
  router.notify();
2078
2077
  await Promise.all(matchPromises);
2079
2078
  },
2079
+ loadMatchData: async routeMatch => {
2080
+ if (isServer || !router.options.useServerData) {
2081
+ var _await$routeMatch$opt;
2082
+
2083
+ return (_await$routeMatch$opt = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
2084
+ // parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
2085
+ params: routeMatch.params,
2086
+ search: routeMatch.routeSearch,
2087
+ signal: routeMatch.__.abortController.signal
2088
+ }))) != null ? _await$routeMatch$opt : {};
2089
+ } else {
2090
+ const next = router.buildNext({
2091
+ to: '.',
2092
+ search: d => _extends({}, d != null ? d : {}, {
2093
+ __data: {
2094
+ matchId: routeMatch.matchId
2095
+ }
2096
+ })
2097
+ });
2098
+ const res = await fetch(next.href, {
2099
+ method: 'GET' // signal: routeMatch.__.abortController.signal,
2100
+
2101
+ });
2102
+
2103
+ if (res.ok) {
2104
+ return res.json();
2105
+ }
2106
+
2107
+ throw new Error('Failed to fetch match data');
2108
+ }
2109
+ },
2080
2110
  invalidateRoute: opts => {
2081
2111
  var _router$state$pending5, _router$state$pending6;
2082
2112
 
@@ -2121,7 +2151,7 @@
2121
2151
  to: next.pathname
2122
2152
  }));
2123
2153
  },
2124
- navigate: async _ref8 => {
2154
+ navigate: async _ref7 => {
2125
2155
  let {
2126
2156
  from,
2127
2157
  to = '.',
@@ -2129,7 +2159,7 @@
2129
2159
  hash,
2130
2160
  replace,
2131
2161
  params
2132
- } = _ref8;
2162
+ } = _ref7;
2133
2163
  // If this link simply reloads the current route,
2134
2164
  // make sure it has a new key so it will trigger a data refresh
2135
2165
  // If this `to` is a valid external URL, return
@@ -2153,8 +2183,8 @@
2153
2183
  params
2154
2184
  });
2155
2185
  },
2156
- buildLink: _ref9 => {
2157
- var _preload, _ref10;
2186
+ buildLink: _ref8 => {
2187
+ var _preload, _ref9;
2158
2188
 
2159
2189
  let {
2160
2190
  from,
@@ -2170,7 +2200,7 @@
2170
2200
  preloadGcMaxAge: userPreloadGcMaxAge,
2171
2201
  preloadDelay: userPreloadDelay,
2172
2202
  disabled
2173
- } = _ref9;
2203
+ } = _ref8;
2174
2204
 
2175
2205
  // If this link simply reloads the current route,
2176
2206
  // make sure it has a new key so it will trigger a data refresh
@@ -2194,7 +2224,7 @@
2194
2224
  };
2195
2225
  const next = router.buildNext(nextOpts);
2196
2226
  preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
2197
- const preloadDelay = (_ref10 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref10 : 0; // Compare path/hash for matches
2227
+ const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
2198
2228
 
2199
2229
  const pathIsEqual = router.state.location.pathname === next.pathname;
2200
2230
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -2295,11 +2325,7 @@
2295
2325
  const recurseRoutes = (routeConfigs, parent) => {
2296
2326
  return routeConfigs.map(routeConfig => {
2297
2327
  const routeOptions = routeConfig.options;
2298
- const route = createRoute(routeConfig, routeOptions, parent, router); // {
2299
- // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
2300
- // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
2301
- // }
2302
-
2328
+ const route = createRoute(routeConfig, routeOptions, parent, router);
2303
2329
  const existingRoute = router.routesById[route.routeId];
2304
2330
 
2305
2331
  if (existingRoute) {
@@ -2409,9 +2435,9 @@
2409
2435
  pathname: next.pathname,
2410
2436
  hash: next.hash,
2411
2437
  search: next.searchStr
2412
- }, {
2438
+ }, _extends({
2413
2439
  id
2414
- });
2440
+ }, next.state));
2415
2441
  } else {
2416
2442
  history.push({
2417
2443
  pathname: next.pathname,
@@ -2434,8 +2460,6 @@
2434
2460
  }
2435
2461
  }
2436
2462
  };
2437
- router.location = router.__.parseLocation(history.location);
2438
- router.state.location = router.location;
2439
2463
  router.update(userOptions); // Allow frameworks to hook into the router creation
2440
2464
 
2441
2465
  router.options.createRouter == null ? void 0 : router.options.createRouter(router);
@@ -2446,7 +2470,16 @@
2446
2470
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
2447
2471
  }
2448
2472
 
2449
- exports.cascadeLoaderData = cascadeLoaderData;
2473
+ function cascadeLoaderData(matches) {
2474
+ matches.forEach((match, index) => {
2475
+ const parent = matches[index - 1];
2476
+
2477
+ if (parent) {
2478
+ match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
2479
+ }
2480
+ });
2481
+ }
2482
+
2450
2483
  exports.cleanPath = cleanPath;
2451
2484
  exports.createBrowserHistory = createBrowserHistory;
2452
2485
  exports.createHashHistory = createHashHistory;
@@ -2468,6 +2501,7 @@
2468
2501
  exports.matchPathname = matchPathname;
2469
2502
  exports.parsePathname = parsePathname;
2470
2503
  exports.parseSearchWith = parseSearchWith;
2504
+ exports.pick = pick;
2471
2505
  exports.replaceEqualDeep = replaceEqualDeep;
2472
2506
  exports.resolvePath = resolvePath;
2473
2507
  exports.rootRouteId = rootRouteId;