@tanstack/react-router 0.0.1-alpha.8 → 0.0.1-beta.1
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.
- package/build/cjs/react-router/src/index.js +51 -7
- package/build/cjs/react-router/src/index.js.map +1 -1
- package/build/cjs/router-core/build/esm/index.js +282 -238
- package/build/cjs/router-core/build/esm/index.js.map +1 -1
- package/build/esm/index.js +332 -246
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +29 -29
- package/build/types/index.d.ts +7 -7
- package/build/umd/index.development.js +334 -246
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -2
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/index.tsx +72 -26
|
@@ -1274,6 +1274,40 @@ function createRoute(routeConfig, options, parent, router) {
|
|
|
1274
1274
|
return router.state.actions[id];
|
|
1275
1275
|
})();
|
|
1276
1276
|
|
|
1277
|
+
const loader = router.state.loaders[id] || (() => {
|
|
1278
|
+
router.state.loaders[id] = {
|
|
1279
|
+
pending: [],
|
|
1280
|
+
fetch: async loaderContext => {
|
|
1281
|
+
if (!route) {
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
const loaderState = {
|
|
1286
|
+
loadedAt: Date.now(),
|
|
1287
|
+
loaderContext
|
|
1288
|
+
};
|
|
1289
|
+
loader.current = loaderState;
|
|
1290
|
+
loader.latest = loaderState;
|
|
1291
|
+
loader.pending.push(loaderState); // router.state = {
|
|
1292
|
+
// ...router.state,
|
|
1293
|
+
// currentAction: loaderState,
|
|
1294
|
+
// latestAction: loaderState,
|
|
1295
|
+
// }
|
|
1296
|
+
|
|
1297
|
+
router.notify();
|
|
1298
|
+
|
|
1299
|
+
try {
|
|
1300
|
+
return await (route.options.loader == null ? void 0 : route.options.loader(loaderContext));
|
|
1301
|
+
} finally {
|
|
1302
|
+
loader.pending = loader.pending.filter(d => d !== loaderState); // router.removeActionQueue.push({ loader, loaderState })
|
|
1303
|
+
|
|
1304
|
+
router.notify();
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
};
|
|
1308
|
+
return router.state.loaders[id];
|
|
1309
|
+
})();
|
|
1310
|
+
|
|
1277
1311
|
let route = {
|
|
1278
1312
|
routeId: id,
|
|
1279
1313
|
routeRouteId: routeId,
|
|
@@ -1284,6 +1318,7 @@ function createRoute(routeConfig, options, parent, router) {
|
|
|
1284
1318
|
childRoutes: undefined,
|
|
1285
1319
|
parentRoute: parent,
|
|
1286
1320
|
action,
|
|
1321
|
+
loader: loader,
|
|
1287
1322
|
buildLink: options => {
|
|
1288
1323
|
return router.buildLink(_extends({}, options, {
|
|
1289
1324
|
from: fullPath
|
|
@@ -1379,12 +1414,10 @@ function createRouteMatch(router, route, opts) {
|
|
|
1379
1414
|
isPending: false,
|
|
1380
1415
|
isFetching: false,
|
|
1381
1416
|
isInvalid: false,
|
|
1417
|
+
invalidAt: Infinity,
|
|
1382
1418
|
getIsInvalid: () => {
|
|
1383
|
-
var _ref, _routeMatch$options$l;
|
|
1384
|
-
|
|
1385
1419
|
const now = Date.now();
|
|
1386
|
-
|
|
1387
|
-
return routeMatch.isInvalid || routeMatch.updatedAt + maxAge < now;
|
|
1420
|
+
return routeMatch.isInvalid || routeMatch.invalidAt < now;
|
|
1388
1421
|
},
|
|
1389
1422
|
__: {
|
|
1390
1423
|
abortController: new AbortController(),
|
|
@@ -1473,9 +1506,33 @@ function createRouteMatch(router, route, opts) {
|
|
|
1473
1506
|
routeMatch.isInvalid = true;
|
|
1474
1507
|
},
|
|
1475
1508
|
hasLoaders: () => {
|
|
1476
|
-
return !!(route.options.loader ||
|
|
1509
|
+
return !!(route.options.loader || elementTypes.some(d => typeof route.options[d] === 'function'));
|
|
1510
|
+
},
|
|
1511
|
+
load: async loaderOpts => {
|
|
1512
|
+
const now = Date.now();
|
|
1513
|
+
const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0; // If this is a preload, add it to the preload cache
|
|
1514
|
+
|
|
1515
|
+
if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
|
|
1516
|
+
// If the match is currently active, don't preload it
|
|
1517
|
+
if (router.state.matches.find(d => d.matchId === routeMatch.matchId)) {
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
router.matchCache[routeMatch.matchId] = {
|
|
1522
|
+
gc: now + loaderOpts.gcMaxAge,
|
|
1523
|
+
match: routeMatch
|
|
1524
|
+
};
|
|
1525
|
+
} // If the match is invalid, errored or idle, trigger it to load
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
if (routeMatch.status === 'success' && routeMatch.getIsInvalid() || routeMatch.status === 'error' || routeMatch.status === 'idle') {
|
|
1529
|
+
const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
|
|
1530
|
+
routeMatch.fetch({
|
|
1531
|
+
maxAge
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1477
1534
|
},
|
|
1478
|
-
|
|
1535
|
+
fetch: async opts => {
|
|
1479
1536
|
const id = '' + Date.now() + Math.random();
|
|
1480
1537
|
routeMatch.__.latestId = id; // If the match was in an error state, set it
|
|
1481
1538
|
// to a loading state again. Otherwise, keep it
|
|
@@ -1494,21 +1551,7 @@ function createRouteMatch(router, route, opts) {
|
|
|
1494
1551
|
routeMatch.__.resolve = resolve;
|
|
1495
1552
|
|
|
1496
1553
|
const loaderPromise = (async () => {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
if (importer) {
|
|
1500
|
-
routeMatch.__.importPromise = importer({
|
|
1501
|
-
params: routeMatch.params // search: routeMatch.search,
|
|
1502
|
-
|
|
1503
|
-
}).then(imported => {
|
|
1504
|
-
routeMatch.__ = _extends({}, routeMatch.__, imported);
|
|
1505
|
-
});
|
|
1506
|
-
} // Wait for the importer to finish before
|
|
1507
|
-
// attempting to load elements and data
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
await routeMatch.__.importPromise; // Next, load the elements and data in parallel
|
|
1511
|
-
|
|
1554
|
+
// Load the elements and data in parallel
|
|
1512
1555
|
routeMatch.__.elementsPromise = (async () => {
|
|
1513
1556
|
// then run all element and data loaders in parallel
|
|
1514
1557
|
// For each element type, potentially load it asynchronously
|
|
@@ -1519,17 +1562,14 @@ function createRouteMatch(router, route, opts) {
|
|
|
1519
1562
|
return;
|
|
1520
1563
|
}
|
|
1521
1564
|
|
|
1522
|
-
|
|
1523
|
-
const res = await routeElement(routeMatch);
|
|
1524
|
-
routeMatch.__[type] = res;
|
|
1525
|
-
} else {
|
|
1526
|
-
routeMatch.__[type] = routeMatch.options[type];
|
|
1527
|
-
}
|
|
1565
|
+
routeMatch.__[type] = await router.options.createElement(routeElement);
|
|
1528
1566
|
}));
|
|
1529
1567
|
})();
|
|
1530
1568
|
|
|
1531
1569
|
routeMatch.__.dataPromise = Promise.resolve().then(async () => {
|
|
1532
1570
|
try {
|
|
1571
|
+
var _ref, _ref2, _opts$maxAge;
|
|
1572
|
+
|
|
1533
1573
|
if (routeMatch.options.loader) {
|
|
1534
1574
|
const data = await routeMatch.options.loader({
|
|
1535
1575
|
params: routeMatch.params,
|
|
@@ -1547,6 +1587,7 @@ function createRouteMatch(router, route, opts) {
|
|
|
1547
1587
|
routeMatch.error = undefined;
|
|
1548
1588
|
routeMatch.status = 'success';
|
|
1549
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);
|
|
1550
1591
|
} catch (err) {
|
|
1551
1592
|
if (id !== routeMatch.__.latestId) {
|
|
1552
1593
|
return routeMatch.__.loaderPromise;
|
|
@@ -1669,13 +1710,15 @@ function createRouter(userOptions) {
|
|
|
1669
1710
|
const originalOptions = _extends({
|
|
1670
1711
|
defaultLoaderGcMaxAge: 5 * 60 * 1000,
|
|
1671
1712
|
defaultLoaderMaxAge: 0,
|
|
1672
|
-
|
|
1713
|
+
defaultPreloadMaxAge: 2000,
|
|
1714
|
+
defaultPreloadDelay: 50
|
|
1673
1715
|
}, userOptions, {
|
|
1674
1716
|
stringifySearch: (_userOptions$stringif = userOptions == null ? void 0 : userOptions.stringifySearch) != null ? _userOptions$stringif : defaultStringifySearch,
|
|
1675
1717
|
parseSearch: (_userOptions$parseSea = userOptions == null ? void 0 : userOptions.parseSearch) != null ? _userOptions$parseSea : defaultParseSearch
|
|
1676
1718
|
});
|
|
1677
1719
|
|
|
1678
1720
|
let router = {
|
|
1721
|
+
history,
|
|
1679
1722
|
options: originalOptions,
|
|
1680
1723
|
listeners: [],
|
|
1681
1724
|
removeActionQueue: [],
|
|
@@ -1694,6 +1737,7 @@ function createRouter(userOptions) {
|
|
|
1694
1737
|
location: null,
|
|
1695
1738
|
matches: [],
|
|
1696
1739
|
actions: {},
|
|
1740
|
+
loaders: {},
|
|
1697
1741
|
loaderData: {},
|
|
1698
1742
|
lastUpdated: Date.now(),
|
|
1699
1743
|
isFetching: false,
|
|
@@ -1718,21 +1762,22 @@ function createRouter(userOptions) {
|
|
|
1718
1762
|
router.listeners.forEach(listener => listener());
|
|
1719
1763
|
},
|
|
1720
1764
|
mount: () => {
|
|
1721
|
-
const next = router.buildLocation({
|
|
1765
|
+
const next = router.__.buildLocation({
|
|
1722
1766
|
to: '.',
|
|
1723
1767
|
search: true,
|
|
1724
1768
|
hash: true
|
|
1725
1769
|
}); // If the current location isn't updated, trigger a navigation
|
|
1726
1770
|
// to the current location. Otherwise, load the current location.
|
|
1727
1771
|
|
|
1772
|
+
|
|
1728
1773
|
if (next.href !== router.location.href) {
|
|
1729
|
-
router.commitLocation(next, true);
|
|
1774
|
+
router.__.commitLocation(next, true);
|
|
1730
1775
|
} else {
|
|
1731
1776
|
router.loadLocation();
|
|
1732
1777
|
}
|
|
1733
1778
|
|
|
1734
1779
|
const unsub = history.listen(event => {
|
|
1735
|
-
router.loadLocation(router.parseLocation(event.location, router.location));
|
|
1780
|
+
router.loadLocation(router.__.parseLocation(event.location, router.location));
|
|
1736
1781
|
}); // addEventListener does not exist in React Native, but window does
|
|
1737
1782
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1738
1783
|
|
|
@@ -1762,169 +1807,11 @@ function createRouter(userOptions) {
|
|
|
1762
1807
|
|
|
1763
1808
|
if (routeConfig) {
|
|
1764
1809
|
router.routesById = {};
|
|
1765
|
-
router.routeTree = router.buildRouteTree(routeConfig);
|
|
1810
|
+
router.routeTree = router.__.buildRouteTree(routeConfig);
|
|
1766
1811
|
}
|
|
1767
1812
|
|
|
1768
1813
|
return router;
|
|
1769
1814
|
},
|
|
1770
|
-
buildRouteTree: rootRouteConfig => {
|
|
1771
|
-
const recurseRoutes = (routeConfigs, parent) => {
|
|
1772
|
-
return routeConfigs.map(routeConfig => {
|
|
1773
|
-
const routeOptions = routeConfig.options;
|
|
1774
|
-
const route = createRoute(routeConfig, routeOptions, parent, router); // {
|
|
1775
|
-
// pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
|
|
1776
|
-
// pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
|
|
1777
|
-
// }
|
|
1778
|
-
|
|
1779
|
-
const existingRoute = router.routesById[route.routeId];
|
|
1780
|
-
|
|
1781
|
-
if (existingRoute) {
|
|
1782
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
1783
|
-
console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
throw new Error();
|
|
1787
|
-
}
|
|
1788
|
-
router.routesById[route.routeId] = route;
|
|
1789
|
-
const children = routeConfig.children;
|
|
1790
|
-
route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
|
|
1791
|
-
return route;
|
|
1792
|
-
});
|
|
1793
|
-
};
|
|
1794
|
-
|
|
1795
|
-
const routes = recurseRoutes([rootRouteConfig]);
|
|
1796
|
-
return routes[0];
|
|
1797
|
-
},
|
|
1798
|
-
parseLocation: (location, previousLocation) => {
|
|
1799
|
-
var _location$hash$split$;
|
|
1800
|
-
|
|
1801
|
-
const parsedSearch = router.options.parseSearch(location.search);
|
|
1802
|
-
return {
|
|
1803
|
-
pathname: location.pathname,
|
|
1804
|
-
searchStr: location.search,
|
|
1805
|
-
search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
|
|
1806
|
-
hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
|
|
1807
|
-
href: "" + location.pathname + location.search + location.hash,
|
|
1808
|
-
state: location.state,
|
|
1809
|
-
key: location.key
|
|
1810
|
-
};
|
|
1811
|
-
},
|
|
1812
|
-
buildLocation: function buildLocation(dest) {
|
|
1813
|
-
var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
|
|
1814
|
-
|
|
1815
|
-
if (dest === void 0) {
|
|
1816
|
-
dest = {};
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
// const resolvedFrom: Location = {
|
|
1820
|
-
// ...router.location,
|
|
1821
|
-
const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
|
|
1822
|
-
|
|
1823
|
-
let pathname = resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
|
|
1824
|
-
|
|
1825
|
-
const fromMatches = router.matchRoutes(router.location.pathname, {
|
|
1826
|
-
strictParseParams: true
|
|
1827
|
-
});
|
|
1828
|
-
const toMatches = router.matchRoutes(pathname);
|
|
1829
|
-
|
|
1830
|
-
const prevParams = _extends({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
|
|
1831
|
-
|
|
1832
|
-
let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
1833
|
-
|
|
1834
|
-
if (nextParams) {
|
|
1835
|
-
toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
1836
|
-
Object.assign({}, nextParams, fn(nextParams));
|
|
1837
|
-
});
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
|
-
pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
|
|
1841
|
-
|
|
1842
|
-
const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), router.location.search) : router.location.search; // Then the link/navigate function
|
|
1843
|
-
|
|
1844
|
-
const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
|
|
1845
|
-
: dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
|
|
1846
|
-
: (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
|
|
1847
|
-
: {}; // Then post filters
|
|
1848
|
-
|
|
1849
|
-
const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
1850
|
-
const search = replaceEqualDeep(router.location.search, postFilteredSearch);
|
|
1851
|
-
const searchStr = router.options.stringifySearch(search);
|
|
1852
|
-
let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
|
|
1853
|
-
hash = hash ? "#" + hash : '';
|
|
1854
|
-
return {
|
|
1855
|
-
pathname,
|
|
1856
|
-
search,
|
|
1857
|
-
searchStr,
|
|
1858
|
-
state: router.location.state,
|
|
1859
|
-
hash,
|
|
1860
|
-
href: "" + pathname + searchStr + hash,
|
|
1861
|
-
key: dest.key
|
|
1862
|
-
};
|
|
1863
|
-
},
|
|
1864
|
-
commitLocation: (next, replace) => {
|
|
1865
|
-
const id = '' + Date.now() + Math.random();
|
|
1866
|
-
if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
|
|
1867
|
-
let nextAction = 'replace';
|
|
1868
|
-
|
|
1869
|
-
if (!replace) {
|
|
1870
|
-
nextAction = 'push';
|
|
1871
|
-
}
|
|
1872
|
-
|
|
1873
|
-
const isSameUrl = router.parseLocation(history.location).href === next.href;
|
|
1874
|
-
|
|
1875
|
-
if (isSameUrl && !next.key) {
|
|
1876
|
-
nextAction = 'replace';
|
|
1877
|
-
}
|
|
1878
|
-
|
|
1879
|
-
if (nextAction === 'replace') {
|
|
1880
|
-
history.replace({
|
|
1881
|
-
pathname: next.pathname,
|
|
1882
|
-
hash: next.hash,
|
|
1883
|
-
search: next.searchStr
|
|
1884
|
-
}, {
|
|
1885
|
-
id
|
|
1886
|
-
});
|
|
1887
|
-
} else {
|
|
1888
|
-
history.push({
|
|
1889
|
-
pathname: next.pathname,
|
|
1890
|
-
hash: next.hash,
|
|
1891
|
-
search: next.searchStr
|
|
1892
|
-
}, {
|
|
1893
|
-
id
|
|
1894
|
-
});
|
|
1895
|
-
}
|
|
1896
|
-
|
|
1897
|
-
router.navigationPromise = new Promise(resolve => {
|
|
1898
|
-
const previousNavigationResolve = router.resolveNavigation;
|
|
1899
|
-
|
|
1900
|
-
router.resolveNavigation = () => {
|
|
1901
|
-
previousNavigationResolve();
|
|
1902
|
-
resolve();
|
|
1903
|
-
};
|
|
1904
|
-
});
|
|
1905
|
-
return router.navigationPromise;
|
|
1906
|
-
},
|
|
1907
|
-
buildNext: opts => {
|
|
1908
|
-
const next = router.buildLocation(opts);
|
|
1909
|
-
const matches = router.matchRoutes(next.pathname);
|
|
1910
|
-
|
|
1911
|
-
const __preSearchFilters = matches.map(match => {
|
|
1912
|
-
var _match$options$preSea;
|
|
1913
|
-
|
|
1914
|
-
return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
|
|
1915
|
-
}).flat().filter(Boolean);
|
|
1916
|
-
|
|
1917
|
-
const __postSearchFilters = matches.map(match => {
|
|
1918
|
-
var _match$options$postSe;
|
|
1919
|
-
|
|
1920
|
-
return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
|
|
1921
|
-
}).flat().filter(Boolean);
|
|
1922
|
-
|
|
1923
|
-
return router.buildLocation(_extends({}, opts, {
|
|
1924
|
-
__preSearchFilters,
|
|
1925
|
-
__postSearchFilters
|
|
1926
|
-
}));
|
|
1927
|
-
},
|
|
1928
1815
|
cancelMatches: () => {
|
|
1929
1816
|
var _router$state$pending, _router$state$pending2;
|
|
1930
1817
|
[...router.state.matches, ...((_router$state$pending = (_router$state$pending2 = router.state.pending) == null ? void 0 : _router$state$pending2.matches) != null ? _router$state$pending : [])].forEach(match => {
|
|
@@ -2027,6 +1914,7 @@ function createRouter(userOptions) {
|
|
|
2027
1914
|
params: d.params,
|
|
2028
1915
|
search: d.search
|
|
2029
1916
|
});
|
|
1917
|
+
delete router.matchCache[d.matchId];
|
|
2030
1918
|
});
|
|
2031
1919
|
|
|
2032
1920
|
if (matches.some(d => d.status === 'loading')) {
|
|
@@ -2066,7 +1954,21 @@ function createRouter(userOptions) {
|
|
|
2066
1954
|
delete router.matchCache[matchId];
|
|
2067
1955
|
});
|
|
2068
1956
|
},
|
|
2069
|
-
loadRoute: async function loadRoute(navigateOpts
|
|
1957
|
+
loadRoute: async function loadRoute(navigateOpts) {
|
|
1958
|
+
if (navigateOpts === void 0) {
|
|
1959
|
+
navigateOpts = router.location;
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
const next = router.buildNext(navigateOpts);
|
|
1963
|
+
const matches = router.matchRoutes(next.pathname, {
|
|
1964
|
+
strictParseParams: true
|
|
1965
|
+
});
|
|
1966
|
+
await router.loadMatches(matches);
|
|
1967
|
+
return matches;
|
|
1968
|
+
},
|
|
1969
|
+
preloadRoute: async function preloadRoute(navigateOpts, loaderOpts) {
|
|
1970
|
+
var _ref4, _ref5, _loaderOpts$maxAge, _ref6, _ref7, _loaderOpts$gcMaxAge;
|
|
1971
|
+
|
|
2070
1972
|
if (navigateOpts === void 0) {
|
|
2071
1973
|
navigateOpts = router.location;
|
|
2072
1974
|
}
|
|
@@ -2077,7 +1979,8 @@ function createRouter(userOptions) {
|
|
|
2077
1979
|
});
|
|
2078
1980
|
await router.loadMatches(matches, {
|
|
2079
1981
|
preload: true,
|
|
2080
|
-
maxAge: loaderOpts.maxAge
|
|
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
|
|
2081
1984
|
});
|
|
2082
1985
|
return matches;
|
|
2083
1986
|
},
|
|
@@ -2171,33 +2074,11 @@ function createRouter(userOptions) {
|
|
|
2171
2074
|
return matches;
|
|
2172
2075
|
},
|
|
2173
2076
|
loadMatches: async (resolvedMatches, loaderOpts) => {
|
|
2174
|
-
const now = Date.now();
|
|
2175
2077
|
const matchPromises = resolvedMatches.map(async match => {
|
|
2176
2078
|
// Validate the match (loads search params etc)
|
|
2177
|
-
match.__.validate();
|
|
2178
|
-
// if (!match.hasLoaders()) {
|
|
2179
|
-
// return
|
|
2180
|
-
// }
|
|
2181
|
-
// If this is a preload, add it to the preload cache
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
if (loaderOpts != null && loaderOpts.preload && (loaderOpts == null ? void 0 : loaderOpts.maxAge) > 0) {
|
|
2185
|
-
// If the match is currently active, don't preload it
|
|
2186
|
-
if (router.state.matches.find(d => d.matchId === match.matchId)) {
|
|
2187
|
-
return;
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
|
-
router.matchCache[match.matchId] = {
|
|
2191
|
-
gc: now + loaderOpts.maxAge,
|
|
2192
|
-
// TODO: Should this use the route's maxAge?
|
|
2193
|
-
match
|
|
2194
|
-
};
|
|
2195
|
-
} // If the match is invalid, errored or idle, trigger it to load
|
|
2196
|
-
|
|
2079
|
+
match.__.validate();
|
|
2197
2080
|
|
|
2198
|
-
|
|
2199
|
-
match.load();
|
|
2200
|
-
}
|
|
2081
|
+
match.load(loaderOpts);
|
|
2201
2082
|
|
|
2202
2083
|
if (match.status === 'loading') {
|
|
2203
2084
|
// If requested, start the pending timers
|
|
@@ -2221,7 +2102,7 @@ function createRouter(userOptions) {
|
|
|
2221
2102
|
}
|
|
2222
2103
|
});
|
|
2223
2104
|
},
|
|
2224
|
-
reload: () => router.
|
|
2105
|
+
reload: () => router.__.navigate({
|
|
2225
2106
|
fromCurrent: true,
|
|
2226
2107
|
replace: true,
|
|
2227
2108
|
search: true
|
|
@@ -2254,11 +2135,7 @@ function createRouter(userOptions) {
|
|
|
2254
2135
|
to: next.pathname
|
|
2255
2136
|
}));
|
|
2256
2137
|
},
|
|
2257
|
-
|
|
2258
|
-
const next = router.buildNext(location);
|
|
2259
|
-
return router.commitLocation(next, location.replace);
|
|
2260
|
-
},
|
|
2261
|
-
navigate: async _ref4 => {
|
|
2138
|
+
navigate: async _ref8 => {
|
|
2262
2139
|
let {
|
|
2263
2140
|
from,
|
|
2264
2141
|
to = '.',
|
|
@@ -2266,7 +2143,7 @@ function createRouter(userOptions) {
|
|
|
2266
2143
|
hash,
|
|
2267
2144
|
replace,
|
|
2268
2145
|
params
|
|
2269
|
-
} =
|
|
2146
|
+
} = _ref8;
|
|
2270
2147
|
// If this link simply reloads the current route,
|
|
2271
2148
|
// make sure it has a new key so it will trigger a data refresh
|
|
2272
2149
|
// If this `to` is a valid external URL, return
|
|
@@ -2281,7 +2158,7 @@ function createRouter(userOptions) {
|
|
|
2281
2158
|
} catch (e) {}
|
|
2282
2159
|
|
|
2283
2160
|
invariant(!isExternal, 'Attempting to navigate to external url with router.navigate!');
|
|
2284
|
-
return router.
|
|
2161
|
+
return router.__.navigate({
|
|
2285
2162
|
from: fromString,
|
|
2286
2163
|
to: toString,
|
|
2287
2164
|
search,
|
|
@@ -2290,8 +2167,8 @@ function createRouter(userOptions) {
|
|
|
2290
2167
|
params
|
|
2291
2168
|
});
|
|
2292
2169
|
},
|
|
2293
|
-
buildLink:
|
|
2294
|
-
var _preload,
|
|
2170
|
+
buildLink: _ref9 => {
|
|
2171
|
+
var _preload, _ref10;
|
|
2295
2172
|
|
|
2296
2173
|
let {
|
|
2297
2174
|
from,
|
|
@@ -2304,9 +2181,10 @@ function createRouter(userOptions) {
|
|
|
2304
2181
|
activeOptions,
|
|
2305
2182
|
preload,
|
|
2306
2183
|
preloadMaxAge: userPreloadMaxAge,
|
|
2184
|
+
preloadGcMaxAge: userPreloadGcMaxAge,
|
|
2307
2185
|
preloadDelay: userPreloadDelay,
|
|
2308
2186
|
disabled
|
|
2309
|
-
} =
|
|
2187
|
+
} = _ref9;
|
|
2310
2188
|
|
|
2311
2189
|
// If this link simply reloads the current route,
|
|
2312
2190
|
// make sure it has a new key so it will trigger a data refresh
|
|
@@ -2329,9 +2207,8 @@ function createRouter(userOptions) {
|
|
|
2329
2207
|
replace
|
|
2330
2208
|
};
|
|
2331
2209
|
const next = router.buildNext(nextOpts);
|
|
2332
|
-
preload = (_preload = preload) != null ? _preload : router.options.
|
|
2333
|
-
const
|
|
2334
|
-
const preloadDelay = (_ref8 = userPreloadDelay != null ? userPreloadDelay : router.options.defaultLinkPreloadDelay) != null ? _ref8 : 0; // Compare path/hash for matches
|
|
2210
|
+
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
|
|
2335
2212
|
|
|
2336
2213
|
const pathIsEqual = router.state.location.pathname === next.pathname;
|
|
2337
2214
|
const currentPathSplit = router.state.location.pathname.split('/');
|
|
@@ -2353,15 +2230,16 @@ function createRouter(userOptions) {
|
|
|
2353
2230
|
} // All is well? Navigate!)
|
|
2354
2231
|
|
|
2355
2232
|
|
|
2356
|
-
router.
|
|
2233
|
+
router.__.navigate(nextOpts);
|
|
2357
2234
|
}
|
|
2358
2235
|
}; // The click handler
|
|
2359
2236
|
|
|
2360
2237
|
|
|
2361
2238
|
const handleFocus = e => {
|
|
2362
|
-
if (preload
|
|
2363
|
-
router.
|
|
2364
|
-
maxAge:
|
|
2239
|
+
if (preload) {
|
|
2240
|
+
router.preloadRoute(nextOpts, {
|
|
2241
|
+
maxAge: userPreloadMaxAge,
|
|
2242
|
+
gcMaxAge: userPreloadGcMaxAge
|
|
2365
2243
|
});
|
|
2366
2244
|
}
|
|
2367
2245
|
};
|
|
@@ -2369,15 +2247,16 @@ function createRouter(userOptions) {
|
|
|
2369
2247
|
const handleEnter = e => {
|
|
2370
2248
|
const target = e.target || {};
|
|
2371
2249
|
|
|
2372
|
-
if (preload
|
|
2250
|
+
if (preload) {
|
|
2373
2251
|
if (target.preloadTimeout) {
|
|
2374
2252
|
return;
|
|
2375
2253
|
}
|
|
2376
2254
|
|
|
2377
2255
|
target.preloadTimeout = setTimeout(() => {
|
|
2378
2256
|
target.preloadTimeout = null;
|
|
2379
|
-
router.
|
|
2380
|
-
maxAge:
|
|
2257
|
+
router.preloadRoute(nextOpts, {
|
|
2258
|
+
maxAge: userPreloadMaxAge,
|
|
2259
|
+
gcMaxAge: userPreloadGcMaxAge
|
|
2381
2260
|
});
|
|
2382
2261
|
}, preloadDelay);
|
|
2383
2262
|
}
|
|
@@ -2402,9 +2281,174 @@ function createRouter(userOptions) {
|
|
|
2402
2281
|
isActive,
|
|
2403
2282
|
disabled
|
|
2404
2283
|
};
|
|
2284
|
+
},
|
|
2285
|
+
buildNext: opts => {
|
|
2286
|
+
const next = router.__.buildLocation(opts);
|
|
2287
|
+
|
|
2288
|
+
const matches = router.matchRoutes(next.pathname);
|
|
2289
|
+
|
|
2290
|
+
const __preSearchFilters = matches.map(match => {
|
|
2291
|
+
var _match$options$preSea;
|
|
2292
|
+
|
|
2293
|
+
return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
|
|
2294
|
+
}).flat().filter(Boolean);
|
|
2295
|
+
|
|
2296
|
+
const __postSearchFilters = matches.map(match => {
|
|
2297
|
+
var _match$options$postSe;
|
|
2298
|
+
|
|
2299
|
+
return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
|
|
2300
|
+
}).flat().filter(Boolean);
|
|
2301
|
+
|
|
2302
|
+
return router.__.buildLocation(_extends({}, opts, {
|
|
2303
|
+
__preSearchFilters,
|
|
2304
|
+
__postSearchFilters
|
|
2305
|
+
}));
|
|
2306
|
+
},
|
|
2307
|
+
__: {
|
|
2308
|
+
buildRouteTree: rootRouteConfig => {
|
|
2309
|
+
const recurseRoutes = (routeConfigs, parent) => {
|
|
2310
|
+
return routeConfigs.map(routeConfig => {
|
|
2311
|
+
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
|
+
|
|
2317
|
+
const existingRoute = router.routesById[route.routeId];
|
|
2318
|
+
|
|
2319
|
+
if (existingRoute) {
|
|
2320
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
2321
|
+
console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
throw new Error();
|
|
2325
|
+
}
|
|
2326
|
+
router.routesById[route.routeId] = route;
|
|
2327
|
+
const children = routeConfig.children;
|
|
2328
|
+
route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
|
|
2329
|
+
return route;
|
|
2330
|
+
});
|
|
2331
|
+
};
|
|
2332
|
+
|
|
2333
|
+
const routes = recurseRoutes([rootRouteConfig]);
|
|
2334
|
+
return routes[0];
|
|
2335
|
+
},
|
|
2336
|
+
parseLocation: (location, previousLocation) => {
|
|
2337
|
+
var _location$hash$split$;
|
|
2338
|
+
|
|
2339
|
+
const parsedSearch = router.options.parseSearch(location.search);
|
|
2340
|
+
return {
|
|
2341
|
+
pathname: location.pathname,
|
|
2342
|
+
searchStr: location.search,
|
|
2343
|
+
search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
|
|
2344
|
+
hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
|
|
2345
|
+
href: "" + location.pathname + location.search + location.hash,
|
|
2346
|
+
state: location.state,
|
|
2347
|
+
key: location.key
|
|
2348
|
+
};
|
|
2349
|
+
},
|
|
2350
|
+
navigate: location => {
|
|
2351
|
+
const next = router.buildNext(location);
|
|
2352
|
+
return router.__.commitLocation(next, location.replace);
|
|
2353
|
+
},
|
|
2354
|
+
buildLocation: function buildLocation(dest) {
|
|
2355
|
+
var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
|
|
2356
|
+
|
|
2357
|
+
if (dest === void 0) {
|
|
2358
|
+
dest = {};
|
|
2359
|
+
}
|
|
2360
|
+
|
|
2361
|
+
// const resolvedFrom: Location = {
|
|
2362
|
+
// ...router.location,
|
|
2363
|
+
const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
|
|
2364
|
+
|
|
2365
|
+
let pathname = resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
|
|
2366
|
+
|
|
2367
|
+
const fromMatches = router.matchRoutes(router.location.pathname, {
|
|
2368
|
+
strictParseParams: true
|
|
2369
|
+
});
|
|
2370
|
+
const toMatches = router.matchRoutes(pathname);
|
|
2371
|
+
|
|
2372
|
+
const prevParams = _extends({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
|
|
2373
|
+
|
|
2374
|
+
let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
2375
|
+
|
|
2376
|
+
if (nextParams) {
|
|
2377
|
+
toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
2378
|
+
Object.assign({}, nextParams, fn(nextParams));
|
|
2379
|
+
});
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
|
|
2383
|
+
|
|
2384
|
+
const preFilteredSearch = (_dest$__preSearchFilt = dest.__preSearchFilters) != null && _dest$__preSearchFilt.length ? dest.__preSearchFilters.reduce((prev, next) => next(prev), router.location.search) : router.location.search; // Then the link/navigate function
|
|
2385
|
+
|
|
2386
|
+
const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
|
|
2387
|
+
: dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
|
|
2388
|
+
: (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
|
|
2389
|
+
: {}; // Then post filters
|
|
2390
|
+
|
|
2391
|
+
const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
2392
|
+
const search = replaceEqualDeep(router.location.search, postFilteredSearch);
|
|
2393
|
+
const searchStr = router.options.stringifySearch(search);
|
|
2394
|
+
let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
|
|
2395
|
+
hash = hash ? "#" + hash : '';
|
|
2396
|
+
return {
|
|
2397
|
+
pathname,
|
|
2398
|
+
search,
|
|
2399
|
+
searchStr,
|
|
2400
|
+
state: router.location.state,
|
|
2401
|
+
hash,
|
|
2402
|
+
href: "" + pathname + searchStr + hash,
|
|
2403
|
+
key: dest.key
|
|
2404
|
+
};
|
|
2405
|
+
},
|
|
2406
|
+
commitLocation: (next, replace) => {
|
|
2407
|
+
const id = '' + Date.now() + Math.random();
|
|
2408
|
+
if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
|
|
2409
|
+
let nextAction = 'replace';
|
|
2410
|
+
|
|
2411
|
+
if (!replace) {
|
|
2412
|
+
nextAction = 'push';
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
const isSameUrl = router.__.parseLocation(history.location).href === next.href;
|
|
2416
|
+
|
|
2417
|
+
if (isSameUrl && !next.key) {
|
|
2418
|
+
nextAction = 'replace';
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
if (nextAction === 'replace') {
|
|
2422
|
+
history.replace({
|
|
2423
|
+
pathname: next.pathname,
|
|
2424
|
+
hash: next.hash,
|
|
2425
|
+
search: next.searchStr
|
|
2426
|
+
}, {
|
|
2427
|
+
id
|
|
2428
|
+
});
|
|
2429
|
+
} else {
|
|
2430
|
+
history.push({
|
|
2431
|
+
pathname: next.pathname,
|
|
2432
|
+
hash: next.hash,
|
|
2433
|
+
search: next.searchStr
|
|
2434
|
+
}, {
|
|
2435
|
+
id
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
|
|
2439
|
+
router.navigationPromise = new Promise(resolve => {
|
|
2440
|
+
const previousNavigationResolve = router.resolveNavigation;
|
|
2441
|
+
|
|
2442
|
+
router.resolveNavigation = () => {
|
|
2443
|
+
previousNavigationResolve();
|
|
2444
|
+
resolve();
|
|
2445
|
+
};
|
|
2446
|
+
});
|
|
2447
|
+
return router.navigationPromise;
|
|
2448
|
+
}
|
|
2405
2449
|
}
|
|
2406
2450
|
};
|
|
2407
|
-
router.location = router.parseLocation(history.location);
|
|
2451
|
+
router.location = router.__.parseLocation(history.location);
|
|
2408
2452
|
router.state.location = router.location;
|
|
2409
2453
|
router.update(userOptions); // Allow frameworks to hook into the router creation
|
|
2410
2454
|
|