@tanstack/react-router 0.0.1-beta.2 → 0.0.1-beta.21

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.
@@ -944,6 +944,12 @@ function functionalUpdate(updater, previous) {
944
944
 
945
945
  return updater;
946
946
  }
947
+ function pick(parent, keys) {
948
+ return keys.reduce((obj, key) => {
949
+ obj[key] = parent[key];
950
+ return obj;
951
+ }, {});
952
+ }
947
953
 
948
954
  function joinPaths(paths) {
949
955
  return cleanPath(paths.filter(Boolean).join('/'));
@@ -1170,6 +1176,7 @@ function toValue(mix) {
1170
1176
  var str = decodeURIComponent(mix);
1171
1177
  if (str === 'false') return false;
1172
1178
  if (str === 'true') return true;
1179
+ if (str.charAt(0) === '0') return str;
1173
1180
  return +str * 0 === 0 ? +str : str;
1174
1181
  }
1175
1182
 
@@ -1220,7 +1227,7 @@ function createRoute(routeConfig, options, parent, router) {
1220
1227
 
1221
1228
  const action = router.state.actions[id] || (() => {
1222
1229
  router.state.actions[id] = {
1223
- pending: [],
1230
+ submissions: [],
1224
1231
  submit: async (submission, actionOpts) => {
1225
1232
  var _actionOpts$invalidat;
1226
1233
 
@@ -1229,18 +1236,20 @@ function createRoute(routeConfig, options, parent, router) {
1229
1236
  }
1230
1237
 
1231
1238
  const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
1239
+
1240
+ if (!(actionOpts != null && actionOpts.multi)) {
1241
+ action.submissions = action.submissions.filter(d => d.isMulti);
1242
+ }
1243
+
1232
1244
  const actionState = {
1233
1245
  submittedAt: Date.now(),
1234
1246
  status: 'pending',
1235
- submission
1247
+ submission,
1248
+ isMulti: !!(actionOpts != null && actionOpts.multi)
1236
1249
  };
1237
1250
  action.current = actionState;
1238
1251
  action.latest = actionState;
1239
- action.pending.push(actionState);
1240
- router.state = _extends({}, router.state, {
1241
- currentAction: actionState,
1242
- latestAction: actionState
1243
- });
1252
+ action.submissions.push(actionState);
1244
1253
  router.notify();
1245
1254
 
1246
1255
  try {
@@ -1262,11 +1271,6 @@ function createRoute(routeConfig, options, parent, router) {
1262
1271
  actionState.error = err;
1263
1272
  actionState.status = 'error';
1264
1273
  } finally {
1265
- action.pending = action.pending.filter(d => d !== actionState);
1266
- router.removeActionQueue.push({
1267
- action,
1268
- actionState
1269
- });
1270
1274
  router.notify();
1271
1275
  }
1272
1276
  }
@@ -1341,15 +1345,6 @@ function createRoute(routeConfig, options, parent, router) {
1341
1345
  });
1342
1346
  return route;
1343
1347
  }
1344
- function cascadeLoaderData(matches) {
1345
- matches.forEach((match, index) => {
1346
- const parent = matches[index - 1];
1347
-
1348
- if (parent) {
1349
- match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
1350
- }
1351
- });
1352
- }
1353
1348
 
1354
1349
  const rootRouteId = '__root__';
1355
1350
  const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId, parentPath) {
@@ -1401,7 +1396,7 @@ const createRouteConfig = function createRouteConfig(options, children, isRoot,
1401
1396
  };
1402
1397
  };
1403
1398
 
1404
- const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1399
+ const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
1405
1400
  function createRouteMatch(router, route, opts) {
1406
1401
  const routeMatch = _extends({}, route, opts, {
1407
1402
  router,
@@ -1411,10 +1406,10 @@ function createRouteMatch(router, route, opts) {
1411
1406
  status: 'idle',
1412
1407
  routeLoaderData: {},
1413
1408
  loaderData: {},
1414
- isPending: false,
1415
1409
  isFetching: false,
1416
1410
  isInvalid: false,
1417
1411
  invalidAt: Infinity,
1412
+ // pendingActions: [],
1418
1413
  getIsInvalid: () => {
1419
1414
  const now = Date.now();
1420
1415
  return routeMatch.isInvalid || routeMatch.invalidAt < now;
@@ -1428,43 +1423,6 @@ function createRouteMatch(router, route, opts) {
1428
1423
 
1429
1424
  routeMatch.router.notify();
1430
1425
  },
1431
- startPending: () => {
1432
- var _routeMatch$options$p, _routeMatch$options$p2;
1433
-
1434
- const pendingMs = (_routeMatch$options$p = routeMatch.options.pendingMs) != null ? _routeMatch$options$p : router.options.defaultPendingMs;
1435
- const pendingMinMs = (_routeMatch$options$p2 = routeMatch.options.pendingMinMs) != null ? _routeMatch$options$p2 : router.options.defaultPendingMinMs;
1436
-
1437
- if (routeMatch.__.pendingTimeout || routeMatch.status !== 'loading' || typeof pendingMs === 'undefined') {
1438
- return;
1439
- }
1440
-
1441
- routeMatch.__.pendingTimeout = setTimeout(() => {
1442
- routeMatch.isPending = true;
1443
-
1444
- routeMatch.__.resolve();
1445
-
1446
- if (typeof pendingMinMs !== 'undefined') {
1447
- routeMatch.__.pendingMinPromise = new Promise(r => routeMatch.__.pendingMinTimeout = setTimeout(r, pendingMinMs));
1448
- }
1449
- }, pendingMs);
1450
- },
1451
- cancelPending: () => {
1452
- routeMatch.isPending = false;
1453
- clearTimeout(routeMatch.__.pendingTimeout);
1454
- clearTimeout(routeMatch.__.pendingMinTimeout);
1455
- delete routeMatch.__.pendingMinPromise;
1456
- },
1457
- // setParentMatch: (parentMatch?: RouteMatch) => {
1458
- // routeMatch.parentMatch = parentMatch
1459
- // },
1460
- // addChildMatch: (childMatch: RouteMatch) => {
1461
- // if (
1462
- // routeMatch.childMatches.find((d) => d.matchId === childMatch.matchId)
1463
- // ) {
1464
- // return
1465
- // }
1466
- // routeMatch.childMatches.push(childMatch)
1467
- // },
1468
1426
  validate: () => {
1469
1427
  var _routeMatch$parentMat, _routeMatch$parentMat2;
1470
1428
 
@@ -1472,9 +1430,11 @@ function createRouteMatch(router, route, opts) {
1472
1430
  const parentSearch = (_routeMatch$parentMat = (_routeMatch$parentMat2 = routeMatch.parentMatch) == null ? void 0 : _routeMatch$parentMat2.search) != null ? _routeMatch$parentMat : router.location.search;
1473
1431
 
1474
1432
  try {
1433
+ var _validator;
1434
+
1475
1435
  const prevSearch = routeMatch.routeSearch;
1476
1436
  const validator = typeof routeMatch.options.validateSearch === 'object' ? routeMatch.options.validateSearch.parse : routeMatch.options.validateSearch;
1477
- let nextSearch = replaceEqualDeep(prevSearch, validator == null ? void 0 : validator(parentSearch)); // Invalidate route matches when search param stability changes
1437
+ let nextSearch = replaceEqualDeep(prevSearch, (_validator = validator == null ? void 0 : validator(parentSearch)) != null ? _validator : {}); // Invalidate route matches when search param stability changes
1478
1438
 
1479
1439
  if (prevSearch !== nextSearch) {
1480
1440
  routeMatch.isInvalid = true;
@@ -1482,6 +1442,13 @@ function createRouteMatch(router, route, opts) {
1482
1442
 
1483
1443
  routeMatch.routeSearch = nextSearch;
1484
1444
  routeMatch.search = replaceEqualDeep(parentSearch, _extends({}, parentSearch, nextSearch));
1445
+ componentTypes.map(async type => {
1446
+ const component = routeMatch.options[type];
1447
+
1448
+ if (typeof routeMatch.__[type] !== 'function') {
1449
+ routeMatch.__[type] = component;
1450
+ }
1451
+ });
1485
1452
  } catch (err) {
1486
1453
  console.error(err);
1487
1454
  const error = new Error('Invalid search params found', {
@@ -1499,14 +1466,16 @@ function createRouteMatch(router, route, opts) {
1499
1466
  var _routeMatch$__$abortC;
1500
1467
 
1501
1468
  (_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
1502
-
1503
- routeMatch.__.cancelPending();
1504
1469
  },
1505
1470
  invalidate: () => {
1506
1471
  routeMatch.isInvalid = true;
1507
1472
  },
1508
1473
  hasLoaders: () => {
1509
- return !!(route.options.loader || elementTypes.some(d => typeof route.options[d] === 'function'));
1474
+ return !!(route.options.loader || componentTypes.some(d => {
1475
+ var _route$options$d;
1476
+
1477
+ return (_route$options$d = route.options[d]) == null ? void 0 : _route$options$d.preload;
1478
+ }));
1510
1479
  },
1511
1480
  load: async loaderOpts => {
1512
1481
  const now = Date.now();
@@ -1527,17 +1496,25 @@ function createRouteMatch(router, route, opts) {
1527
1496
 
1528
1497
  if (routeMatch.status === 'success' && routeMatch.getIsInvalid() || routeMatch.status === 'error' || routeMatch.status === 'idle') {
1529
1498
  const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
1530
- routeMatch.fetch({
1499
+ await routeMatch.fetch({
1531
1500
  maxAge
1532
1501
  });
1533
1502
  }
1534
1503
  },
1535
1504
  fetch: async opts => {
1536
- const id = '' + Date.now() + Math.random();
1537
- routeMatch.__.latestId = id; // If the match was in an error state, set it
1505
+ const loadId = '' + Date.now() + Math.random();
1506
+ routeMatch.__.latestId = loadId;
1507
+
1508
+ const checkLatest = async () => {
1509
+ if (loadId !== routeMatch.__.latestId) {
1510
+ // warning(true, 'Data loader is out of date!')
1511
+ return new Promise(() => {});
1512
+ }
1513
+ }; // If the match was in an error state, set it
1538
1514
  // to a loading state again. Otherwise, keep it
1539
1515
  // as loading or resolved
1540
1516
 
1517
+
1541
1518
  if (routeMatch.status === 'idle') {
1542
1519
  routeMatch.status = 'loading';
1543
1520
  } // We started loading the route, so it's no longer invalid
@@ -1550,94 +1527,66 @@ function createRouteMatch(router, route, opts) {
1550
1527
  routeMatch.isFetching = true;
1551
1528
  routeMatch.__.resolve = resolve;
1552
1529
 
1553
- const loaderPromise = (async () => {
1554
- // Load the elements and data in parallel
1555
- routeMatch.__.elementsPromise = (async () => {
1556
- // then run all element and data loaders in parallel
1557
- // For each element type, potentially load it asynchronously
1558
- await Promise.all(elementTypes.map(async type => {
1559
- const routeElement = routeMatch.options[type];
1530
+ routeMatch.__.componentsPromise = (async () => {
1531
+ // then run all component and data loaders in parallel
1532
+ // For each component type, potentially load it asynchronously
1533
+ await Promise.all(componentTypes.map(async type => {
1534
+ var _routeMatch$__$type;
1560
1535
 
1561
- if (routeMatch.__[type]) {
1562
- return;
1563
- }
1536
+ const component = routeMatch.options[type];
1564
1537
 
1565
- routeMatch.__[type] = await router.options.createElement(routeElement);
1566
- }));
1567
- })();
1568
-
1569
- routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1570
- try {
1571
- var _ref, _ref2, _opts$maxAge;
1572
-
1573
- if (routeMatch.options.loader) {
1574
- const data = await routeMatch.options.loader({
1575
- params: routeMatch.params,
1576
- search: routeMatch.routeSearch,
1577
- signal: routeMatch.__.abortController.signal
1578
- });
1579
-
1580
- if (id !== routeMatch.__.latestId) {
1581
- return routeMatch.__.loaderPromise;
1582
- }
1583
-
1584
- routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1585
- }
1586
-
1587
- routeMatch.error = undefined;
1588
- routeMatch.status = 'success';
1589
- routeMatch.updatedAt = Date.now();
1590
- 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);
1591
- } catch (err) {
1592
- if (id !== routeMatch.__.latestId) {
1593
- return routeMatch.__.loaderPromise;
1594
- }
1595
-
1596
- if (process.env.NODE_ENV !== 'production') {
1597
- console.error(err);
1598
- }
1599
-
1600
- routeMatch.error = err;
1601
- routeMatch.status = 'error';
1602
- routeMatch.updatedAt = Date.now();
1538
+ if ((_routeMatch$__$type = routeMatch.__[type]) != null && _routeMatch$__$type.preload) {
1539
+ routeMatch.__[type] = await router.options.loadComponent(component);
1603
1540
  }
1604
- });
1541
+ }));
1542
+ })();
1605
1543
 
1544
+ routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1606
1545
  try {
1607
- await Promise.all([routeMatch.__.elementsPromise, routeMatch.__.dataPromise]);
1546
+ var _ref, _ref2, _opts$maxAge;
1608
1547
 
1609
- if (id !== routeMatch.__.latestId) {
1610
- return routeMatch.__.loaderPromise;
1548
+ if (routeMatch.options.loader) {
1549
+ const data = await router.loadMatchData(routeMatch);
1550
+ await checkLatest();
1551
+ routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1611
1552
  }
1612
1553
 
1613
- if (routeMatch.__.pendingMinPromise) {
1614
- await routeMatch.__.pendingMinPromise;
1615
- delete routeMatch.__.pendingMinPromise;
1616
- }
1617
- } finally {
1618
- if (id !== routeMatch.__.latestId) {
1619
- return routeMatch.__.loaderPromise;
1620
- }
1621
-
1622
- routeMatch.__.cancelPending();
1554
+ routeMatch.error = undefined;
1555
+ routeMatch.status = 'success';
1556
+ routeMatch.updatedAt = Date.now();
1557
+ 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);
1558
+ return routeMatch.routeLoaderData;
1559
+ } catch (err) {
1560
+ await checkLatest();
1623
1561
 
1624
- routeMatch.isPending = false;
1625
- routeMatch.isFetching = false;
1562
+ if (process.env.NODE_ENV !== 'production') {
1563
+ console.error(err);
1564
+ }
1626
1565
 
1627
- routeMatch.__.notify();
1566
+ routeMatch.error = err;
1567
+ routeMatch.status = 'error';
1568
+ routeMatch.updatedAt = Date.now();
1569
+ throw err;
1628
1570
  }
1629
- })();
1571
+ });
1630
1572
 
1631
- routeMatch.__.loaderPromise = loaderPromise;
1632
- await loaderPromise;
1573
+ const after = async () => {
1574
+ await checkLatest();
1575
+ routeMatch.isFetching = false;
1576
+ delete routeMatch.__.loadPromise;
1633
1577
 
1634
- if (id !== routeMatch.__.latestId) {
1635
- return routeMatch.__.loaderPromise;
1636
- }
1578
+ routeMatch.__.notify();
1579
+ };
1637
1580
 
1638
- delete routeMatch.__.loaderPromise;
1581
+ try {
1582
+ await Promise.all([routeMatch.__.componentsPromise, routeMatch.__.dataPromise.catch(() => {})]);
1583
+ after();
1584
+ } catch (_unused) {
1585
+ after();
1586
+ }
1639
1587
  });
1640
- return await routeMatch.__.loadPromise;
1588
+ await routeMatch.__.loadPromise;
1589
+ await checkLatest();
1641
1590
  }
1642
1591
  });
1643
1592
 
@@ -1698,9 +1647,22 @@ function stringifySearchWith(stringify) {
1698
1647
 
1699
1648
  var _window$document;
1700
1649
  // Detect if we're in the DOM
1701
- const isServer = Boolean(typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement)); // This is the default history object if none is defined
1650
+ const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement); // This is the default history object if none is defined
1702
1651
 
1703
- const createDefaultHistory = () => !isServer ? createBrowserHistory() : createMemoryHistory();
1652
+ const createDefaultHistory = () => isServer ? createMemoryHistory() : createBrowserHistory();
1653
+
1654
+ function getInitialRouterState() {
1655
+ return {
1656
+ status: 'idle',
1657
+ location: null,
1658
+ matches: [],
1659
+ actions: {},
1660
+ loaders: {},
1661
+ lastUpdated: Date.now(),
1662
+ isFetching: false,
1663
+ isPreloading: false
1664
+ };
1665
+ }
1704
1666
 
1705
1667
  function createRouter(userOptions) {
1706
1668
  var _userOptions$stringif, _userOptions$parseSea;
@@ -1718,30 +1680,24 @@ function createRouter(userOptions) {
1718
1680
  });
1719
1681
 
1720
1682
  let router = {
1683
+ types: undefined,
1684
+ // public api
1721
1685
  history,
1722
1686
  options: originalOptions,
1723
1687
  listeners: [],
1724
- removeActionQueue: [],
1725
1688
  // Resolved after construction
1726
1689
  basepath: '',
1727
1690
  routeTree: undefined,
1728
1691
  routesById: {},
1729
1692
  location: undefined,
1730
- allRouteInfo: undefined,
1731
1693
  //
1732
1694
  navigationPromise: Promise.resolve(),
1733
1695
  resolveNavigation: () => {},
1734
1696
  matchCache: {},
1735
- state: {
1736
- status: 'idle',
1737
- location: null,
1738
- matches: [],
1739
- actions: {},
1740
- loaders: {},
1741
- loaderData: {},
1742
- lastUpdated: Date.now(),
1743
- isFetching: false,
1744
- isPreloading: false
1697
+ state: getInitialRouterState(),
1698
+ reset: () => {
1699
+ router.state = getInitialRouterState();
1700
+ router.notify();
1745
1701
  },
1746
1702
  startedLoadingAt: Date.now(),
1747
1703
  subscribe: listener => {
@@ -1754,13 +1710,39 @@ function createRouter(userOptions) {
1754
1710
  return router.routesById[id];
1755
1711
  },
1756
1712
  notify: () => {
1757
- router.state = _extends({}, router.state, {
1758
- isFetching: router.state.status === 'loading' || router.state.matches.some(d => d.isFetching),
1759
- isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
1760
- });
1713
+ const isFetching = router.state.status === 'loading' || router.state.matches.some(d => d.isFetching);
1714
+ const isPreloading = Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId));
1715
+
1716
+ if (router.state.isFetching !== isFetching || router.state.isPreloading !== isPreloading) {
1717
+ router.state = _extends({}, router.state, {
1718
+ isFetching,
1719
+ isPreloading
1720
+ });
1721
+ }
1722
+
1761
1723
  cascadeLoaderData(router.state.matches);
1762
1724
  router.listeners.forEach(listener => listener(router));
1763
1725
  },
1726
+ dehydrateState: () => {
1727
+ return _extends({}, pick(router.state, ['status', 'location', 'lastUpdated']), {
1728
+ matches: router.state.matches.map(match => pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
1729
+ });
1730
+ },
1731
+ hydrateState: dehydratedState => {
1732
+ // Match the routes
1733
+ const matches = router.matchRoutes(router.location.pathname, {
1734
+ strictParseParams: true
1735
+ });
1736
+ matches.forEach((match, index) => {
1737
+ const dehydratedMatch = dehydratedState.matches[index];
1738
+ invariant(dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
1739
+ Object.assign(match, dehydratedMatch);
1740
+ });
1741
+ matches.forEach(match => match.__.validate());
1742
+ router.state = _extends({}, router.state, dehydratedState, {
1743
+ matches
1744
+ });
1745
+ },
1764
1746
  mount: () => {
1765
1747
  const next = router.__.buildLocation({
1766
1748
  to: '.',
@@ -1772,12 +1754,14 @@ function createRouter(userOptions) {
1772
1754
 
1773
1755
  if (next.href !== router.location.href) {
1774
1756
  router.__.commitLocation(next, true);
1775
- } else {
1776
- router.loadLocation();
1777
1757
  }
1778
1758
 
1779
- const unsub = history.listen(event => {
1780
- router.loadLocation(router.__.parseLocation(event.location, router.location));
1759
+ if (!router.state.matches.length) {
1760
+ router.load();
1761
+ }
1762
+
1763
+ const unsub = router.history.listen(event => {
1764
+ router.load(router.__.parseLocation(event.location, router.location));
1781
1765
  }); // addEventListener does not exist in React Native, but window does
1782
1766
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1783
1767
 
@@ -1788,16 +1772,30 @@ function createRouter(userOptions) {
1788
1772
  }
1789
1773
 
1790
1774
  return () => {
1791
- unsub(); // Be sure to unsubscribe if a new handler is set
1775
+ unsub();
1792
1776
 
1793
- window.removeEventListener('visibilitychange', router.onFocus);
1794
- window.removeEventListener('focus', router.onFocus);
1777
+ if (!isServer && window.removeEventListener) {
1778
+ // Be sure to unsubscribe if a new handler is set
1779
+ window.removeEventListener('visibilitychange', router.onFocus);
1780
+ window.removeEventListener('focus', router.onFocus);
1781
+ }
1795
1782
  };
1796
1783
  },
1797
1784
  onFocus: () => {
1798
- router.loadLocation();
1785
+ router.load();
1799
1786
  },
1800
1787
  update: opts => {
1788
+ const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
1789
+
1790
+ if (!router.location || newHistory) {
1791
+ if (opts != null && opts.history) {
1792
+ router.history = opts.history;
1793
+ }
1794
+
1795
+ router.location = router.__.parseLocation(router.history.location);
1796
+ router.state.location = router.location;
1797
+ }
1798
+
1801
1799
  Object.assign(router.options, opts);
1802
1800
  const {
1803
1801
  basepath,
@@ -1818,49 +1816,41 @@ function createRouter(userOptions) {
1818
1816
  match.cancel();
1819
1817
  });
1820
1818
  },
1821
- loadLocation: async next => {
1819
+ load: async next => {
1822
1820
  const id = Math.random();
1823
1821
  router.startedLoadingAt = id;
1824
1822
 
1825
1823
  if (next) {
1826
1824
  // Ingest the new location
1827
1825
  router.location = next;
1828
- } // Clear out old actions
1826
+ } // Cancel any pending matches
1829
1827
 
1830
1828
 
1831
- router.removeActionQueue.forEach(_ref => {
1832
- let {
1833
- action,
1834
- actionState
1835
- } = _ref;
1836
-
1837
- if (router.state.currentAction === actionState) {
1838
- router.state.currentAction = undefined;
1839
- }
1840
-
1841
- if (action.current === actionState) {
1842
- action.current = undefined;
1843
- }
1844
- });
1845
- router.removeActionQueue = []; // Cancel any pending matches
1846
-
1847
1829
  router.cancelMatches(); // Match the routes
1848
1830
 
1849
- const matches = router.matchRoutes(location.pathname, {
1831
+ const matches = router.matchRoutes(router.location.pathname, {
1850
1832
  strictParseParams: true
1851
1833
  });
1852
- router.state = _extends({}, router.state, {
1853
- pending: {
1834
+
1835
+ if (typeof document !== 'undefined') {
1836
+ router.state = _extends({}, router.state, {
1837
+ pending: {
1838
+ matches: matches,
1839
+ location: router.location
1840
+ },
1841
+ status: 'loading'
1842
+ });
1843
+ } else {
1844
+ router.state = _extends({}, router.state, {
1854
1845
  matches: matches,
1855
- location: router.location
1856
- },
1857
- status: 'loading'
1858
- });
1846
+ location: router.location,
1847
+ status: 'loading'
1848
+ });
1849
+ }
1850
+
1859
1851
  router.notify(); // Load the matches
1860
1852
 
1861
- await router.loadMatches(matches, {
1862
- withPending: true
1863
- });
1853
+ await router.loadMatches(matches);
1864
1854
 
1865
1855
  if (router.startedLoadingAt !== id) {
1866
1856
  // Ignore side-effects of match loading
@@ -1877,9 +1867,12 @@ function createRouter(userOptions) {
1877
1867
  exiting.push(d);
1878
1868
  }
1879
1869
  });
1870
+ const entering = matches.filter(d => {
1871
+ return !previousMatches.find(dd => dd.matchId === d.matchId);
1872
+ });
1880
1873
  const now = Date.now();
1881
1874
  exiting.forEach(d => {
1882
- var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
1875
+ var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
1883
1876
 
1884
1877
  d.__.onExit == null ? void 0 : d.__.onExit({
1885
1878
  params: d.params,
@@ -1891,7 +1884,7 @@ function createRouter(userOptions) {
1891
1884
  d.error = undefined;
1892
1885
  }
1893
1886
 
1894
- 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);
1887
+ 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);
1895
1888
 
1896
1889
  if (gc > 0) {
1897
1890
  router.matchCache[d.matchId] = {
@@ -1906,9 +1899,6 @@ function createRouter(userOptions) {
1906
1899
  search: d.routeSearch
1907
1900
  });
1908
1901
  });
1909
- const entering = matches.filter(d => {
1910
- return !previousMatches.find(dd => dd.matchId === d.matchId);
1911
- });
1912
1902
  entering.forEach(d => {
1913
1903
  d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
1914
1904
  params: d.params,
@@ -1917,16 +1907,18 @@ function createRouter(userOptions) {
1917
1907
  delete router.matchCache[d.matchId];
1918
1908
  });
1919
1909
 
1920
- if (matches.some(d => d.status === 'loading')) {
1921
- router.notify();
1922
- await Promise.all(matches.map(d => d.__.loaderPromise || Promise.resolve()));
1923
- }
1924
-
1925
1910
  if (router.startedLoadingAt !== id) {
1926
1911
  // Ignore side-effects of match loading
1927
1912
  return;
1928
1913
  }
1929
1914
 
1915
+ matches.forEach(match => {
1916
+ // Clear actions
1917
+ if (match.action) {
1918
+ match.action.current = undefined;
1919
+ match.action.submissions = [];
1920
+ }
1921
+ });
1930
1922
  router.state = _extends({}, router.state, {
1931
1923
  location: router.location,
1932
1924
  matches,
@@ -1967,7 +1959,7 @@ function createRouter(userOptions) {
1967
1959
  return matches;
1968
1960
  },
1969
1961
  preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
1970
- var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
1962
+ var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
1971
1963
 
1972
1964
  if (navigateOpts === void 0) {
1973
1965
  navigateOpts = router.location;
@@ -1979,8 +1971,8 @@ function createRouter(userOptions) {
1979
1971
  });
1980
1972
  await router.loadMatches(matches, {
1981
1973
  preload: true,
1982
- maxAge: (_ref4 = (_ref5 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref5 : router.options.defaultLoaderMaxAge) != null ? _ref4 : 0,
1983
- gcMaxAge: (_ref6 = (_ref7 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref7 : router.options.defaultLoaderGcMaxAge) != null ? _ref6 : 0
1974
+ maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
1975
+ gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
1984
1976
  });
1985
1977
  return matches;
1986
1978
  },
@@ -2056,6 +2048,7 @@ function createRouter(userOptions) {
2056
2048
  const interpolatedPath = interpolatePath(foundRoute.routePath, params);
2057
2049
  const matchId = interpolatePath(foundRoute.routeId, params, true);
2058
2050
  const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || createRouteMatch(router, foundRoute, {
2051
+ parentMatch,
2059
2052
  matchId,
2060
2053
  params,
2061
2054
  pathname: joinPaths([pathname, interpolatedPath])
@@ -2079,18 +2072,51 @@ function createRouter(userOptions) {
2079
2072
  match.__.validate();
2080
2073
 
2081
2074
  match.load(loaderOpts);
2075
+ const search = match.search;
2082
2076
 
2083
- if (match.status === 'loading') {
2084
- // If requested, start the pending timers
2085
- if (loaderOpts != null && loaderOpts.withPending) match.__.startPending(); // Wait for the first sign of activity from the match
2086
- // This might be completion, error, or a pending state
2077
+ if (search.__data && search.__data.matchId !== match.matchId) {
2078
+ return;
2079
+ }
2087
2080
 
2081
+ if (match.__.loadPromise) {
2082
+ // Wait for the first sign of activity from the match
2088
2083
  await match.__.loadPromise;
2089
2084
  }
2090
2085
  });
2091
2086
  router.notify();
2092
2087
  await Promise.all(matchPromises);
2093
2088
  },
2089
+ loadMatchData: async routeMatch => {
2090
+ if (isServer || !router.options.useServerData) {
2091
+ var _await$routeMatch$opt;
2092
+
2093
+ return (_await$routeMatch$opt = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
2094
+ // parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
2095
+ params: routeMatch.params,
2096
+ search: routeMatch.routeSearch,
2097
+ signal: routeMatch.__.abortController.signal
2098
+ }))) != null ? _await$routeMatch$opt : {};
2099
+ } else {
2100
+ const next = router.buildNext({
2101
+ to: '.',
2102
+ search: d => _extends({}, d != null ? d : {}, {
2103
+ __data: {
2104
+ matchId: routeMatch.matchId
2105
+ }
2106
+ })
2107
+ });
2108
+ const res = await fetch(next.href, {
2109
+ method: 'GET' // signal: routeMatch.__.abortController.signal,
2110
+
2111
+ });
2112
+
2113
+ if (res.ok) {
2114
+ return res.json();
2115
+ }
2116
+
2117
+ throw new Error('Failed to fetch match data');
2118
+ }
2119
+ },
2094
2120
  invalidateRoute: opts => {
2095
2121
  var _router$state$pending5, _router$state$pending6;
2096
2122
 
@@ -2135,7 +2161,7 @@ function createRouter(userOptions) {
2135
2161
  to: next.pathname
2136
2162
  }));
2137
2163
  },
2138
- navigate: async _ref8 => {
2164
+ navigate: async _ref7 => {
2139
2165
  let {
2140
2166
  from,
2141
2167
  to = '.',
@@ -2143,7 +2169,7 @@ function createRouter(userOptions) {
2143
2169
  hash,
2144
2170
  replace,
2145
2171
  params
2146
- } = _ref8;
2172
+ } = _ref7;
2147
2173
  // If this link simply reloads the current route,
2148
2174
  // make sure it has a new key so it will trigger a data refresh
2149
2175
  // If this `to` is a valid external URL, return
@@ -2167,8 +2193,8 @@ function createRouter(userOptions) {
2167
2193
  params
2168
2194
  });
2169
2195
  },
2170
- buildLink: _ref9 => {
2171
- var _preload, _ref10;
2196
+ buildLink: _ref8 => {
2197
+ var _preload, _ref9;
2172
2198
 
2173
2199
  let {
2174
2200
  from,
@@ -2184,7 +2210,7 @@ function createRouter(userOptions) {
2184
2210
  preloadGcMaxAge: userPreloadGcMaxAge,
2185
2211
  preloadDelay: userPreloadDelay,
2186
2212
  disabled
2187
- } = _ref9;
2213
+ } = _ref8;
2188
2214
 
2189
2215
  // If this link simply reloads the current route,
2190
2216
  // make sure it has a new key so it will trigger a data refresh
@@ -2208,7 +2234,7 @@ function createRouter(userOptions) {
2208
2234
  };
2209
2235
  const next = router.buildNext(nextOpts);
2210
2236
  preload = (_preload = preload) != null ? _preload : router.options.defaultPreload;
2211
- const preloadDelay = (_ref10 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref10 : 0; // Compare path/hash for matches
2237
+ const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
2212
2238
 
2213
2239
  const pathIsEqual = router.state.location.pathname === next.pathname;
2214
2240
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -2309,11 +2335,7 @@ function createRouter(userOptions) {
2309
2335
  const recurseRoutes = (routeConfigs, parent) => {
2310
2336
  return routeConfigs.map(routeConfig => {
2311
2337
  const routeOptions = routeConfig.options;
2312
- const route = createRoute(routeConfig, routeOptions, parent, router); // {
2313
- // pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
2314
- // pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
2315
- // }
2316
-
2338
+ const route = createRoute(routeConfig, routeOptions, parent, router);
2317
2339
  const existingRoute = router.routesById[route.routeId];
2318
2340
 
2319
2341
  if (existingRoute) {
@@ -2423,9 +2445,9 @@ function createRouter(userOptions) {
2423
2445
  pathname: next.pathname,
2424
2446
  hash: next.hash,
2425
2447
  search: next.searchStr
2426
- }, {
2448
+ }, _extends({
2427
2449
  id
2428
- });
2450
+ }, next.state));
2429
2451
  } else {
2430
2452
  history.push({
2431
2453
  pathname: next.pathname,
@@ -2448,8 +2470,6 @@ function createRouter(userOptions) {
2448
2470
  }
2449
2471
  }
2450
2472
  };
2451
- router.location = router.__.parseLocation(history.location);
2452
- router.state.location = router.location;
2453
2473
  router.update(userOptions); // Allow frameworks to hook into the router creation
2454
2474
 
2455
2475
  router.options.createRouter == null ? void 0 : router.options.createRouter(router);
@@ -2460,7 +2480,16 @@ function isCtrlEvent(e) {
2460
2480
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
2461
2481
  }
2462
2482
 
2463
- exports.cascadeLoaderData = cascadeLoaderData;
2483
+ function cascadeLoaderData(matches) {
2484
+ matches.forEach((match, index) => {
2485
+ const parent = matches[index - 1];
2486
+
2487
+ if (parent) {
2488
+ match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
2489
+ }
2490
+ });
2491
+ }
2492
+
2464
2493
  exports.cleanPath = cleanPath;
2465
2494
  exports.createBrowserHistory = createBrowserHistory;
2466
2495
  exports.createHashHistory = createHashHistory;
@@ -2482,6 +2511,7 @@ exports.matchByPath = matchByPath;
2482
2511
  exports.matchPathname = matchPathname;
2483
2512
  exports.parsePathname = parsePathname;
2484
2513
  exports.parseSearchWith = parseSearchWith;
2514
+ exports.pick = pick;
2485
2515
  exports.replaceEqualDeep = replaceEqualDeep;
2486
2516
  exports.resolvePath = resolvePath;
2487
2517
  exports.rootRouteId = rootRouteId;