@tanstack/router-core 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.
@@ -930,6 +930,12 @@ function functionalUpdate(updater, previous) {
930
930
 
931
931
  return updater;
932
932
  }
933
+ function pick(parent, keys) {
934
+ return keys.reduce((obj, key) => {
935
+ obj[key] = parent[key];
936
+ return obj;
937
+ }, {});
938
+ }
933
939
 
934
940
  function joinPaths(paths) {
935
941
  return cleanPath(paths.filter(Boolean).join('/'));
@@ -1156,6 +1162,7 @@ function toValue(mix) {
1156
1162
  var str = decodeURIComponent(mix);
1157
1163
  if (str === 'false') return false;
1158
1164
  if (str === 'true') return true;
1165
+ if (str.charAt(0) === '0') return str;
1159
1166
  return +str * 0 === 0 ? +str : str;
1160
1167
  }
1161
1168
 
@@ -1206,7 +1213,7 @@ function createRoute(routeConfig, options, parent, router) {
1206
1213
 
1207
1214
  const action = router.state.actions[id] || (() => {
1208
1215
  router.state.actions[id] = {
1209
- pending: [],
1216
+ submissions: [],
1210
1217
  submit: async (submission, actionOpts) => {
1211
1218
  var _actionOpts$invalidat;
1212
1219
 
@@ -1215,18 +1222,20 @@ function createRoute(routeConfig, options, parent, router) {
1215
1222
  }
1216
1223
 
1217
1224
  const invalidate = (_actionOpts$invalidat = actionOpts == null ? void 0 : actionOpts.invalidate) != null ? _actionOpts$invalidat : true;
1225
+
1226
+ if (!(actionOpts != null && actionOpts.multi)) {
1227
+ action.submissions = action.submissions.filter(d => d.isMulti);
1228
+ }
1229
+
1218
1230
  const actionState = {
1219
1231
  submittedAt: Date.now(),
1220
1232
  status: 'pending',
1221
- submission
1233
+ submission,
1234
+ isMulti: !!(actionOpts != null && actionOpts.multi)
1222
1235
  };
1223
1236
  action.current = actionState;
1224
1237
  action.latest = actionState;
1225
- action.pending.push(actionState);
1226
- router.state = _extends({}, router.state, {
1227
- currentAction: actionState,
1228
- latestAction: actionState
1229
- });
1238
+ action.submissions.push(actionState);
1230
1239
  router.notify();
1231
1240
 
1232
1241
  try {
@@ -1248,11 +1257,6 @@ function createRoute(routeConfig, options, parent, router) {
1248
1257
  actionState.error = err;
1249
1258
  actionState.status = 'error';
1250
1259
  } finally {
1251
- action.pending = action.pending.filter(d => d !== actionState);
1252
- router.removeActionQueue.push({
1253
- action,
1254
- actionState
1255
- });
1256
1260
  router.notify();
1257
1261
  }
1258
1262
  }
@@ -1327,15 +1331,6 @@ function createRoute(routeConfig, options, parent, router) {
1327
1331
  });
1328
1332
  return route;
1329
1333
  }
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
1334
 
1340
1335
  const rootRouteId = '__root__';
1341
1336
  const createRouteConfig = function createRouteConfig(options, children, isRoot, parentId, parentPath) {
@@ -1387,7 +1382,7 @@ const createRouteConfig = function createRouteConfig(options, children, isRoot,
1387
1382
  };
1388
1383
  };
1389
1384
 
1390
- const elementTypes = ['element', 'errorElement', 'catchElement', 'pendingElement'];
1385
+ const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
1391
1386
  function createRouteMatch(router, route, opts) {
1392
1387
  const routeMatch = _extends({}, route, opts, {
1393
1388
  router,
@@ -1397,10 +1392,10 @@ function createRouteMatch(router, route, opts) {
1397
1392
  status: 'idle',
1398
1393
  routeLoaderData: {},
1399
1394
  loaderData: {},
1400
- isPending: false,
1401
1395
  isFetching: false,
1402
1396
  isInvalid: false,
1403
1397
  invalidAt: Infinity,
1398
+ // pendingActions: [],
1404
1399
  getIsInvalid: () => {
1405
1400
  const now = Date.now();
1406
1401
  return routeMatch.isInvalid || routeMatch.invalidAt < now;
@@ -1414,43 +1409,6 @@ function createRouteMatch(router, route, opts) {
1414
1409
 
1415
1410
  routeMatch.router.notify();
1416
1411
  },
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
1412
  validate: () => {
1455
1413
  var _routeMatch$parentMat, _routeMatch$parentMat2;
1456
1414
 
@@ -1458,9 +1416,11 @@ function createRouteMatch(router, route, opts) {
1458
1416
  const parentSearch = (_routeMatch$parentMat = (_routeMatch$parentMat2 = routeMatch.parentMatch) == null ? void 0 : _routeMatch$parentMat2.search) != null ? _routeMatch$parentMat : router.location.search;
1459
1417
 
1460
1418
  try {
1419
+ var _validator;
1420
+
1461
1421
  const prevSearch = routeMatch.routeSearch;
1462
1422
  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
1423
+ let nextSearch = replaceEqualDeep(prevSearch, (_validator = validator == null ? void 0 : validator(parentSearch)) != null ? _validator : {}); // Invalidate route matches when search param stability changes
1464
1424
 
1465
1425
  if (prevSearch !== nextSearch) {
1466
1426
  routeMatch.isInvalid = true;
@@ -1468,6 +1428,13 @@ function createRouteMatch(router, route, opts) {
1468
1428
 
1469
1429
  routeMatch.routeSearch = nextSearch;
1470
1430
  routeMatch.search = replaceEqualDeep(parentSearch, _extends({}, parentSearch, nextSearch));
1431
+ componentTypes.map(async type => {
1432
+ const component = routeMatch.options[type];
1433
+
1434
+ if (typeof routeMatch.__[type] !== 'function') {
1435
+ routeMatch.__[type] = component;
1436
+ }
1437
+ });
1471
1438
  } catch (err) {
1472
1439
  console.error(err);
1473
1440
  const error = new Error('Invalid search params found', {
@@ -1485,14 +1452,16 @@ function createRouteMatch(router, route, opts) {
1485
1452
  var _routeMatch$__$abortC;
1486
1453
 
1487
1454
  (_routeMatch$__$abortC = routeMatch.__.abortController) == null ? void 0 : _routeMatch$__$abortC.abort();
1488
-
1489
- routeMatch.__.cancelPending();
1490
1455
  },
1491
1456
  invalidate: () => {
1492
1457
  routeMatch.isInvalid = true;
1493
1458
  },
1494
1459
  hasLoaders: () => {
1495
- return !!(route.options.loader || elementTypes.some(d => typeof route.options[d] === 'function'));
1460
+ return !!(route.options.loader || componentTypes.some(d => {
1461
+ var _route$options$d;
1462
+
1463
+ return (_route$options$d = route.options[d]) == null ? void 0 : _route$options$d.preload;
1464
+ }));
1496
1465
  },
1497
1466
  load: async loaderOpts => {
1498
1467
  const now = Date.now();
@@ -1513,17 +1482,25 @@ function createRouteMatch(router, route, opts) {
1513
1482
 
1514
1483
  if (routeMatch.status === 'success' && routeMatch.getIsInvalid() || routeMatch.status === 'error' || routeMatch.status === 'idle') {
1515
1484
  const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
1516
- routeMatch.fetch({
1485
+ await routeMatch.fetch({
1517
1486
  maxAge
1518
1487
  });
1519
1488
  }
1520
1489
  },
1521
1490
  fetch: async opts => {
1522
- const id = '' + Date.now() + Math.random();
1523
- routeMatch.__.latestId = id; // If the match was in an error state, set it
1491
+ const loadId = '' + Date.now() + Math.random();
1492
+ routeMatch.__.latestId = loadId;
1493
+
1494
+ const checkLatest = async () => {
1495
+ if (loadId !== routeMatch.__.latestId) {
1496
+ // warning(true, 'Data loader is out of date!')
1497
+ return new Promise(() => {});
1498
+ }
1499
+ }; // If the match was in an error state, set it
1524
1500
  // to a loading state again. Otherwise, keep it
1525
1501
  // as loading or resolved
1526
1502
 
1503
+
1527
1504
  if (routeMatch.status === 'idle') {
1528
1505
  routeMatch.status = 'loading';
1529
1506
  } // We started loading the route, so it's no longer invalid
@@ -1536,94 +1513,66 @@ function createRouteMatch(router, route, opts) {
1536
1513
  routeMatch.isFetching = true;
1537
1514
  routeMatch.__.resolve = resolve;
1538
1515
 
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];
1516
+ routeMatch.__.componentsPromise = (async () => {
1517
+ // then run all component and data loaders in parallel
1518
+ // For each component type, potentially load it asynchronously
1519
+ await Promise.all(componentTypes.map(async type => {
1520
+ var _routeMatch$__$type;
1546
1521
 
1547
- if (routeMatch.__[type]) {
1548
- return;
1549
- }
1522
+ const component = routeMatch.options[type];
1550
1523
 
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;
1558
-
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
- });
1565
-
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
- if (process.env.NODE_ENV !== 'production') {
1583
- console.error(err);
1584
- }
1585
-
1586
- routeMatch.error = err;
1587
- routeMatch.status = 'error';
1588
- routeMatch.updatedAt = Date.now();
1524
+ if ((_routeMatch$__$type = routeMatch.__[type]) != null && _routeMatch$__$type.preload) {
1525
+ routeMatch.__[type] = await router.options.loadComponent(component);
1589
1526
  }
1590
- });
1527
+ }));
1528
+ })();
1591
1529
 
1530
+ routeMatch.__.dataPromise = Promise.resolve().then(async () => {
1592
1531
  try {
1593
- await Promise.all([routeMatch.__.elementsPromise, routeMatch.__.dataPromise]);
1532
+ var _ref, _ref2, _opts$maxAge;
1594
1533
 
1595
- if (id !== routeMatch.__.latestId) {
1596
- return routeMatch.__.loaderPromise;
1534
+ if (routeMatch.options.loader) {
1535
+ const data = await router.loadMatchData(routeMatch);
1536
+ await checkLatest();
1537
+ routeMatch.routeLoaderData = replaceEqualDeep(routeMatch.routeLoaderData, data);
1597
1538
  }
1598
1539
 
1599
- if (routeMatch.__.pendingMinPromise) {
1600
- await routeMatch.__.pendingMinPromise;
1601
- delete routeMatch.__.pendingMinPromise;
1602
- }
1603
- } finally {
1604
- if (id !== routeMatch.__.latestId) {
1605
- return routeMatch.__.loaderPromise;
1606
- }
1607
-
1608
- routeMatch.__.cancelPending();
1540
+ routeMatch.error = undefined;
1541
+ routeMatch.status = 'success';
1542
+ routeMatch.updatedAt = Date.now();
1543
+ 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);
1544
+ return routeMatch.routeLoaderData;
1545
+ } catch (err) {
1546
+ await checkLatest();
1609
1547
 
1610
- routeMatch.isPending = false;
1611
- routeMatch.isFetching = false;
1548
+ if (process.env.NODE_ENV !== 'production') {
1549
+ console.error(err);
1550
+ }
1612
1551
 
1613
- routeMatch.__.notify();
1552
+ routeMatch.error = err;
1553
+ routeMatch.status = 'error';
1554
+ routeMatch.updatedAt = Date.now();
1555
+ throw err;
1614
1556
  }
1615
- })();
1557
+ });
1616
1558
 
1617
- routeMatch.__.loaderPromise = loaderPromise;
1618
- await loaderPromise;
1559
+ const after = async () => {
1560
+ await checkLatest();
1561
+ routeMatch.isFetching = false;
1562
+ delete routeMatch.__.loadPromise;
1619
1563
 
1620
- if (id !== routeMatch.__.latestId) {
1621
- return routeMatch.__.loaderPromise;
1622
- }
1564
+ routeMatch.__.notify();
1565
+ };
1623
1566
 
1624
- delete routeMatch.__.loaderPromise;
1567
+ try {
1568
+ await Promise.all([routeMatch.__.componentsPromise, routeMatch.__.dataPromise.catch(() => {})]);
1569
+ after();
1570
+ } catch (_unused) {
1571
+ after();
1572
+ }
1625
1573
  });
1626
- return await routeMatch.__.loadPromise;
1574
+ await routeMatch.__.loadPromise;
1575
+ await checkLatest();
1627
1576
  }
1628
1577
  });
1629
1578
 
@@ -1684,9 +1633,22 @@ function stringifySearchWith(stringify) {
1684
1633
 
1685
1634
  var _window$document;
1686
1635
  // 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
1636
+ const isServer = typeof window === 'undefined' || !((_window$document = window.document) != null && _window$document.createElement); // This is the default history object if none is defined
1688
1637
 
1689
- const createDefaultHistory = () => !isServer ? createBrowserHistory() : createMemoryHistory();
1638
+ const createDefaultHistory = () => isServer ? createMemoryHistory() : createBrowserHistory();
1639
+
1640
+ function getInitialRouterState() {
1641
+ return {
1642
+ status: 'idle',
1643
+ location: null,
1644
+ matches: [],
1645
+ actions: {},
1646
+ loaders: {},
1647
+ lastUpdated: Date.now(),
1648
+ isFetching: false,
1649
+ isPreloading: false
1650
+ };
1651
+ }
1690
1652
 
1691
1653
  function createRouter(userOptions) {
1692
1654
  var _userOptions$stringif, _userOptions$parseSea;
@@ -1704,30 +1666,24 @@ function createRouter(userOptions) {
1704
1666
  });
1705
1667
 
1706
1668
  let router = {
1669
+ types: undefined,
1670
+ // public api
1707
1671
  history,
1708
1672
  options: originalOptions,
1709
1673
  listeners: [],
1710
- removeActionQueue: [],
1711
1674
  // Resolved after construction
1712
1675
  basepath: '',
1713
1676
  routeTree: undefined,
1714
1677
  routesById: {},
1715
1678
  location: undefined,
1716
- allRouteInfo: undefined,
1717
1679
  //
1718
1680
  navigationPromise: Promise.resolve(),
1719
1681
  resolveNavigation: () => {},
1720
1682
  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
1683
+ state: getInitialRouterState(),
1684
+ reset: () => {
1685
+ router.state = getInitialRouterState();
1686
+ router.notify();
1731
1687
  },
1732
1688
  startedLoadingAt: Date.now(),
1733
1689
  subscribe: listener => {
@@ -1740,13 +1696,39 @@ function createRouter(userOptions) {
1740
1696
  return router.routesById[id];
1741
1697
  },
1742
1698
  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
- });
1699
+ const isFetching = router.state.status === 'loading' || router.state.matches.some(d => d.isFetching);
1700
+ const isPreloading = Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId));
1701
+
1702
+ if (router.state.isFetching !== isFetching || router.state.isPreloading !== isPreloading) {
1703
+ router.state = _extends({}, router.state, {
1704
+ isFetching,
1705
+ isPreloading
1706
+ });
1707
+ }
1708
+
1747
1709
  cascadeLoaderData(router.state.matches);
1748
1710
  router.listeners.forEach(listener => listener(router));
1749
1711
  },
1712
+ dehydrateState: () => {
1713
+ return _extends({}, pick(router.state, ['status', 'location', 'lastUpdated']), {
1714
+ matches: router.state.matches.map(match => pick(match, ['matchId', 'status', 'routeLoaderData', 'loaderData', 'isInvalid', 'invalidAt']))
1715
+ });
1716
+ },
1717
+ hydrateState: dehydratedState => {
1718
+ // Match the routes
1719
+ const matches = router.matchRoutes(router.location.pathname, {
1720
+ strictParseParams: true
1721
+ });
1722
+ matches.forEach((match, index) => {
1723
+ const dehydratedMatch = dehydratedState.matches[index];
1724
+ invariant(dehydratedMatch, 'Oh no! Dehydrated route matches did not match the active state of the router 😬');
1725
+ Object.assign(match, dehydratedMatch);
1726
+ });
1727
+ matches.forEach(match => match.__.validate());
1728
+ router.state = _extends({}, router.state, dehydratedState, {
1729
+ matches
1730
+ });
1731
+ },
1750
1732
  mount: () => {
1751
1733
  const next = router.__.buildLocation({
1752
1734
  to: '.',
@@ -1758,12 +1740,14 @@ function createRouter(userOptions) {
1758
1740
 
1759
1741
  if (next.href !== router.location.href) {
1760
1742
  router.__.commitLocation(next, true);
1761
- } else {
1762
- router.loadLocation();
1763
1743
  }
1764
1744
 
1765
- const unsub = history.listen(event => {
1766
- router.loadLocation(router.__.parseLocation(event.location, router.location));
1745
+ if (!router.state.matches.length) {
1746
+ router.load();
1747
+ }
1748
+
1749
+ const unsub = router.history.listen(event => {
1750
+ router.load(router.__.parseLocation(event.location, router.location));
1767
1751
  }); // addEventListener does not exist in React Native, but window does
1768
1752
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
1769
1753
 
@@ -1774,16 +1758,30 @@ function createRouter(userOptions) {
1774
1758
  }
1775
1759
 
1776
1760
  return () => {
1777
- unsub(); // Be sure to unsubscribe if a new handler is set
1761
+ unsub();
1778
1762
 
1779
- window.removeEventListener('visibilitychange', router.onFocus);
1780
- window.removeEventListener('focus', router.onFocus);
1763
+ if (!isServer && window.removeEventListener) {
1764
+ // Be sure to unsubscribe if a new handler is set
1765
+ window.removeEventListener('visibilitychange', router.onFocus);
1766
+ window.removeEventListener('focus', router.onFocus);
1767
+ }
1781
1768
  };
1782
1769
  },
1783
1770
  onFocus: () => {
1784
- router.loadLocation();
1771
+ router.load();
1785
1772
  },
1786
1773
  update: opts => {
1774
+ const newHistory = (opts == null ? void 0 : opts.history) !== router.history;
1775
+
1776
+ if (!router.location || newHistory) {
1777
+ if (opts != null && opts.history) {
1778
+ router.history = opts.history;
1779
+ }
1780
+
1781
+ router.location = router.__.parseLocation(router.history.location);
1782
+ router.state.location = router.location;
1783
+ }
1784
+
1787
1785
  Object.assign(router.options, opts);
1788
1786
  const {
1789
1787
  basepath,
@@ -1804,49 +1802,41 @@ function createRouter(userOptions) {
1804
1802
  match.cancel();
1805
1803
  });
1806
1804
  },
1807
- loadLocation: async next => {
1805
+ load: async next => {
1808
1806
  const id = Math.random();
1809
1807
  router.startedLoadingAt = id;
1810
1808
 
1811
1809
  if (next) {
1812
1810
  // Ingest the new location
1813
1811
  router.location = next;
1814
- } // Clear out old actions
1812
+ } // Cancel any pending matches
1815
1813
 
1816
1814
 
1817
- router.removeActionQueue.forEach(_ref => {
1818
- let {
1819
- action,
1820
- actionState
1821
- } = _ref;
1822
-
1823
- if (router.state.currentAction === actionState) {
1824
- router.state.currentAction = undefined;
1825
- }
1826
-
1827
- if (action.current === actionState) {
1828
- action.current = undefined;
1829
- }
1830
- });
1831
- router.removeActionQueue = []; // Cancel any pending matches
1832
-
1833
1815
  router.cancelMatches(); // Match the routes
1834
1816
 
1835
- const matches = router.matchRoutes(location.pathname, {
1817
+ const matches = router.matchRoutes(router.location.pathname, {
1836
1818
  strictParseParams: true
1837
1819
  });
1838
- router.state = _extends({}, router.state, {
1839
- pending: {
1820
+
1821
+ if (typeof document !== 'undefined') {
1822
+ router.state = _extends({}, router.state, {
1823
+ pending: {
1824
+ matches: matches,
1825
+ location: router.location
1826
+ },
1827
+ status: 'loading'
1828
+ });
1829
+ } else {
1830
+ router.state = _extends({}, router.state, {
1840
1831
  matches: matches,
1841
- location: router.location
1842
- },
1843
- status: 'loading'
1844
- });
1832
+ location: router.location,
1833
+ status: 'loading'
1834
+ });
1835
+ }
1836
+
1845
1837
  router.notify(); // Load the matches
1846
1838
 
1847
- await router.loadMatches(matches, {
1848
- withPending: true
1849
- });
1839
+ await router.loadMatches(matches);
1850
1840
 
1851
1841
  if (router.startedLoadingAt !== id) {
1852
1842
  // Ignore side-effects of match loading
@@ -1863,9 +1853,12 @@ function createRouter(userOptions) {
1863
1853
  exiting.push(d);
1864
1854
  }
1865
1855
  });
1856
+ const entering = matches.filter(d => {
1857
+ return !previousMatches.find(dd => dd.matchId === d.matchId);
1858
+ });
1866
1859
  const now = Date.now();
1867
1860
  exiting.forEach(d => {
1868
- var _ref2, _d$options$loaderGcMa, _ref3, _d$options$loaderMaxA;
1861
+ var _ref, _d$options$loaderGcMa, _ref2, _d$options$loaderMaxA;
1869
1862
 
1870
1863
  d.__.onExit == null ? void 0 : d.__.onExit({
1871
1864
  params: d.params,
@@ -1877,7 +1870,7 @@ function createRouter(userOptions) {
1877
1870
  d.error = undefined;
1878
1871
  }
1879
1872
 
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);
1873
+ 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
1874
 
1882
1875
  if (gc > 0) {
1883
1876
  router.matchCache[d.matchId] = {
@@ -1892,9 +1885,6 @@ function createRouter(userOptions) {
1892
1885
  search: d.routeSearch
1893
1886
  });
1894
1887
  });
1895
- const entering = matches.filter(d => {
1896
- return !previousMatches.find(dd => dd.matchId === d.matchId);
1897
- });
1898
1888
  entering.forEach(d => {
1899
1889
  d.__.onExit = d.options.onMatch == null ? void 0 : d.options.onMatch({
1900
1890
  params: d.params,
@@ -1903,16 +1893,18 @@ function createRouter(userOptions) {
1903
1893
  delete router.matchCache[d.matchId];
1904
1894
  });
1905
1895
 
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
1896
  if (router.startedLoadingAt !== id) {
1912
1897
  // Ignore side-effects of match loading
1913
1898
  return;
1914
1899
  }
1915
1900
 
1901
+ matches.forEach(match => {
1902
+ // Clear actions
1903
+ if (match.action) {
1904
+ match.action.current = undefined;
1905
+ match.action.submissions = [];
1906
+ }
1907
+ });
1916
1908
  router.state = _extends({}, router.state, {
1917
1909
  location: router.location,
1918
1910
  matches,
@@ -1953,7 +1945,7 @@ function createRouter(userOptions) {
1953
1945
  return matches;
1954
1946
  },
1955
1947
  preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
1956
- var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
1948
+ var _ref3, _ref4, _loaderOpts$maxAge, _ref5, _ref6, _loaderOpts$gcMaxAge;
1957
1949
 
1958
1950
  if (navigateOpts === void 0) {
1959
1951
  navigateOpts = router.location;
@@ -1965,8 +1957,8 @@ function createRouter(userOptions) {
1965
1957
  });
1966
1958
  await router.loadMatches(matches, {
1967
1959
  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
1960
+ maxAge: (_ref3 = (_ref4 = (_loaderOpts$maxAge = loaderOpts.maxAge) != null ? _loaderOpts$maxAge : router.options.defaultPreloadMaxAge) != null ? _ref4 : router.options.defaultLoaderMaxAge) != null ? _ref3 : 0,
1961
+ gcMaxAge: (_ref5 = (_ref6 = (_loaderOpts$gcMaxAge = loaderOpts.gcMaxAge) != null ? _loaderOpts$gcMaxAge : router.options.defaultPreloadGcMaxAge) != null ? _ref6 : router.options.defaultLoaderGcMaxAge) != null ? _ref5 : 0
1970
1962
  });
1971
1963
  return matches;
1972
1964
  },
@@ -2042,6 +2034,7 @@ function createRouter(userOptions) {
2042
2034
  const interpolatedPath = interpolatePath(foundRoute.routePath, params);
2043
2035
  const matchId = interpolatePath(foundRoute.routeId, params, true);
2044
2036
  const match = existingMatches.find(d => d.matchId === matchId) || ((_router$matchCache$ma = router.matchCache[matchId]) == null ? void 0 : _router$matchCache$ma.match) || createRouteMatch(router, foundRoute, {
2037
+ parentMatch,
2045
2038
  matchId,
2046
2039
  params,
2047
2040
  pathname: joinPaths([pathname, interpolatedPath])
@@ -2065,18 +2058,51 @@ function createRouter(userOptions) {
2065
2058
  match.__.validate();
2066
2059
 
2067
2060
  match.load(loaderOpts);
2061
+ const search = match.search;
2068
2062
 
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
2063
+ if (search.__data && search.__data.matchId !== match.matchId) {
2064
+ return;
2065
+ }
2073
2066
 
2067
+ if (match.__.loadPromise) {
2068
+ // Wait for the first sign of activity from the match
2074
2069
  await match.__.loadPromise;
2075
2070
  }
2076
2071
  });
2077
2072
  router.notify();
2078
2073
  await Promise.all(matchPromises);
2079
2074
  },
2075
+ loadMatchData: async routeMatch => {
2076
+ if (isServer || !router.options.useServerData) {
2077
+ var _await$routeMatch$opt;
2078
+
2079
+ return (_await$routeMatch$opt = await (routeMatch.options.loader == null ? void 0 : routeMatch.options.loader({
2080
+ // parentLoaderPromise: routeMatch.parentMatch?.__.dataPromise,
2081
+ params: routeMatch.params,
2082
+ search: routeMatch.routeSearch,
2083
+ signal: routeMatch.__.abortController.signal
2084
+ }))) != null ? _await$routeMatch$opt : {};
2085
+ } else {
2086
+ const next = router.buildNext({
2087
+ to: '.',
2088
+ search: d => _extends({}, d != null ? d : {}, {
2089
+ __data: {
2090
+ matchId: routeMatch.matchId
2091
+ }
2092
+ })
2093
+ });
2094
+ const res = await fetch(next.href, {
2095
+ method: 'GET' // signal: routeMatch.__.abortController.signal,
2096
+
2097
+ });
2098
+
2099
+ if (res.ok) {
2100
+ return res.json();
2101
+ }
2102
+
2103
+ throw new Error('Failed to fetch match data');
2104
+ }
2105
+ },
2080
2106
  invalidateRoute: opts => {
2081
2107
  var _router$state$pending5, _router$state$pending6;
2082
2108
 
@@ -2121,7 +2147,7 @@ function createRouter(userOptions) {
2121
2147
  to: next.pathname
2122
2148
  }));
2123
2149
  },
2124
- navigate: async _ref8 => {
2150
+ navigate: async _ref7 => {
2125
2151
  let {
2126
2152
  from,
2127
2153
  to = '.',
@@ -2129,7 +2155,7 @@ function createRouter(userOptions) {
2129
2155
  hash,
2130
2156
  replace,
2131
2157
  params
2132
- } = _ref8;
2158
+ } = _ref7;
2133
2159
  // If this link simply reloads the current route,
2134
2160
  // make sure it has a new key so it will trigger a data refresh
2135
2161
  // If this `to` is a valid external URL, return
@@ -2153,8 +2179,8 @@ function createRouter(userOptions) {
2153
2179
  params
2154
2180
  });
2155
2181
  },
2156
- buildLink: _ref9 => {
2157
- var _preload, _ref10;
2182
+ buildLink: _ref8 => {
2183
+ var _preload, _ref9;
2158
2184
 
2159
2185
  let {
2160
2186
  from,
@@ -2170,7 +2196,7 @@ function createRouter(userOptions) {
2170
2196
  preloadGcMaxAge: userPreloadGcMaxAge,
2171
2197
  preloadDelay: userPreloadDelay,
2172
2198
  disabled
2173
- } = _ref9;
2199
+ } = _ref8;
2174
2200
 
2175
2201
  // If this link simply reloads the current route,
2176
2202
  // make sure it has a new key so it will trigger a data refresh
@@ -2194,7 +2220,7 @@ function createRouter(userOptions) {
2194
2220
  };
2195
2221
  const next = router.buildNext(nextOpts);
2196
2222
  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
2223
+ const preloadDelay = (_ref9 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultPreloadDelay) != null ? _ref9 : 0; // Compare path/hash for matches
2198
2224
 
2199
2225
  const pathIsEqual = router.state.location.pathname === next.pathname;
2200
2226
  const currentPathSplit = router.state.location.pathname.split('/');
@@ -2295,11 +2321,7 @@ function createRouter(userOptions) {
2295
2321
  const recurseRoutes = (routeConfigs, parent) => {
2296
2322
  return routeConfigs.map(routeConfig => {
2297
2323
  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
-
2324
+ const route = createRoute(routeConfig, routeOptions, parent, router);
2303
2325
  const existingRoute = router.routesById[route.routeId];
2304
2326
 
2305
2327
  if (existingRoute) {
@@ -2409,9 +2431,9 @@ function createRouter(userOptions) {
2409
2431
  pathname: next.pathname,
2410
2432
  hash: next.hash,
2411
2433
  search: next.searchStr
2412
- }, {
2434
+ }, _extends({
2413
2435
  id
2414
- });
2436
+ }, next.state));
2415
2437
  } else {
2416
2438
  history.push({
2417
2439
  pathname: next.pathname,
@@ -2434,8 +2456,6 @@ function createRouter(userOptions) {
2434
2456
  }
2435
2457
  }
2436
2458
  };
2437
- router.location = router.__.parseLocation(history.location);
2438
- router.state.location = router.location;
2439
2459
  router.update(userOptions); // Allow frameworks to hook into the router creation
2440
2460
 
2441
2461
  router.options.createRouter == null ? void 0 : router.options.createRouter(router);
@@ -2446,5 +2466,15 @@ function isCtrlEvent(e) {
2446
2466
  return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
2447
2467
  }
2448
2468
 
2449
- export { cascadeLoaderData, cleanPath, createBrowserHistory, createHashHistory, createMemoryHistory, createRoute, createRouteConfig, createRouteMatch, createRouter, decode, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, interpolatePath, invariant, joinPaths, last, matchByPath, matchPathname, parsePathname, parseSearchWith, replaceEqualDeep, resolvePath, rootRouteId, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, warning };
2469
+ function cascadeLoaderData(matches) {
2470
+ matches.forEach((match, index) => {
2471
+ const parent = matches[index - 1];
2472
+
2473
+ if (parent) {
2474
+ match.loaderData = replaceEqualDeep(match.loaderData, _extends({}, parent.loaderData, match.routeLoaderData));
2475
+ }
2476
+ });
2477
+ }
2478
+
2479
+ export { cleanPath, createBrowserHistory, createHashHistory, createMemoryHistory, createRoute, createRouteConfig, createRouteMatch, createRouter, decode, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, interpolatePath, invariant, joinPaths, last, matchByPath, matchPathname, parsePathname, parseSearchWith, pick, replaceEqualDeep, resolvePath, rootRouteId, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, warning };
2450
2480
  //# sourceMappingURL=index.js.map