@tanstack/react-router 0.0.1-alpha.9 → 0.0.1-beta.2
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 +52 -8
- package/build/cjs/react-router/src/index.js.map +1 -1
- package/build/cjs/router-core/build/esm/index.js +243 -217
- package/build/cjs/router-core/build/esm/index.js.map +1 -1
- package/build/esm/index.js +294 -226
- 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 +296 -226
- 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 +3 -3
- package/src/index.tsx +73 -26
- package/src/qss.ts +0 -53
|
@@ -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
|
|
@@ -1471,9 +1506,33 @@ function createRouteMatch(router, route, opts) {
|
|
|
1471
1506
|
routeMatch.isInvalid = true;
|
|
1472
1507
|
},
|
|
1473
1508
|
hasLoaders: () => {
|
|
1474
|
-
return !!(route.options.loader ||
|
|
1509
|
+
return !!(route.options.loader || elementTypes.some(d => typeof route.options[d] === 'function'));
|
|
1475
1510
|
},
|
|
1476
|
-
load: async
|
|
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
|
+
}
|
|
1534
|
+
},
|
|
1535
|
+
fetch: async opts => {
|
|
1477
1536
|
const id = '' + Date.now() + Math.random();
|
|
1478
1537
|
routeMatch.__.latestId = id; // If the match was in an error state, set it
|
|
1479
1538
|
// to a loading state again. Otherwise, keep it
|
|
@@ -1492,21 +1551,7 @@ function createRouteMatch(router, route, opts) {
|
|
|
1492
1551
|
routeMatch.__.resolve = resolve;
|
|
1493
1552
|
|
|
1494
1553
|
const loaderPromise = (async () => {
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
if (importer) {
|
|
1498
|
-
routeMatch.__.importPromise = importer({
|
|
1499
|
-
params: routeMatch.params // search: routeMatch.search,
|
|
1500
|
-
|
|
1501
|
-
}).then(imported => {
|
|
1502
|
-
routeMatch.__ = _extends({}, routeMatch.__, imported);
|
|
1503
|
-
});
|
|
1504
|
-
} // Wait for the importer to finish before
|
|
1505
|
-
// attempting to load elements and data
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
await routeMatch.__.importPromise; // Next, load the elements and data in parallel
|
|
1509
|
-
|
|
1554
|
+
// Load the elements and data in parallel
|
|
1510
1555
|
routeMatch.__.elementsPromise = (async () => {
|
|
1511
1556
|
// then run all element and data loaders in parallel
|
|
1512
1557
|
// For each element type, potentially load it asynchronously
|
|
@@ -1517,12 +1562,7 @@ function createRouteMatch(router, route, opts) {
|
|
|
1517
1562
|
return;
|
|
1518
1563
|
}
|
|
1519
1564
|
|
|
1520
|
-
|
|
1521
|
-
const res = await routeElement(routeMatch);
|
|
1522
|
-
routeMatch.__[type] = res;
|
|
1523
|
-
} else {
|
|
1524
|
-
routeMatch.__[type] = routeMatch.options[type];
|
|
1525
|
-
}
|
|
1565
|
+
routeMatch.__[type] = await router.options.createElement(routeElement);
|
|
1526
1566
|
}));
|
|
1527
1567
|
})();
|
|
1528
1568
|
|
|
@@ -1678,6 +1718,7 @@ function createRouter(userOptions) {
|
|
|
1678
1718
|
});
|
|
1679
1719
|
|
|
1680
1720
|
let router = {
|
|
1721
|
+
history,
|
|
1681
1722
|
options: originalOptions,
|
|
1682
1723
|
listeners: [],
|
|
1683
1724
|
removeActionQueue: [],
|
|
@@ -1696,6 +1737,7 @@ function createRouter(userOptions) {
|
|
|
1696
1737
|
location: null,
|
|
1697
1738
|
matches: [],
|
|
1698
1739
|
actions: {},
|
|
1740
|
+
loaders: {},
|
|
1699
1741
|
loaderData: {},
|
|
1700
1742
|
lastUpdated: Date.now(),
|
|
1701
1743
|
isFetching: false,
|
|
@@ -1717,24 +1759,25 @@ function createRouter(userOptions) {
|
|
|
1717
1759
|
isPreloading: Object.values(router.matchCache).some(d => d.match.isFetching && !router.state.matches.find(dd => dd.matchId === d.match.matchId))
|
|
1718
1760
|
});
|
|
1719
1761
|
cascadeLoaderData(router.state.matches);
|
|
1720
|
-
router.listeners.forEach(listener => listener());
|
|
1762
|
+
router.listeners.forEach(listener => listener(router));
|
|
1721
1763
|
},
|
|
1722
1764
|
mount: () => {
|
|
1723
|
-
const next = router.buildLocation({
|
|
1765
|
+
const next = router.__.buildLocation({
|
|
1724
1766
|
to: '.',
|
|
1725
1767
|
search: true,
|
|
1726
1768
|
hash: true
|
|
1727
1769
|
}); // If the current location isn't updated, trigger a navigation
|
|
1728
1770
|
// to the current location. Otherwise, load the current location.
|
|
1729
1771
|
|
|
1772
|
+
|
|
1730
1773
|
if (next.href !== router.location.href) {
|
|
1731
|
-
router.commitLocation(next, true);
|
|
1774
|
+
router.__.commitLocation(next, true);
|
|
1732
1775
|
} else {
|
|
1733
1776
|
router.loadLocation();
|
|
1734
1777
|
}
|
|
1735
1778
|
|
|
1736
1779
|
const unsub = history.listen(event => {
|
|
1737
|
-
router.loadLocation(router.parseLocation(event.location, router.location));
|
|
1780
|
+
router.loadLocation(router.__.parseLocation(event.location, router.location));
|
|
1738
1781
|
}); // addEventListener does not exist in React Native, but window does
|
|
1739
1782
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
1740
1783
|
|
|
@@ -1764,169 +1807,11 @@ function createRouter(userOptions) {
|
|
|
1764
1807
|
|
|
1765
1808
|
if (routeConfig) {
|
|
1766
1809
|
router.routesById = {};
|
|
1767
|
-
router.routeTree = router.buildRouteTree(routeConfig);
|
|
1810
|
+
router.routeTree = router.__.buildRouteTree(routeConfig);
|
|
1768
1811
|
}
|
|
1769
1812
|
|
|
1770
1813
|
return router;
|
|
1771
1814
|
},
|
|
1772
|
-
buildRouteTree: rootRouteConfig => {
|
|
1773
|
-
const recurseRoutes = (routeConfigs, parent) => {
|
|
1774
|
-
return routeConfigs.map(routeConfig => {
|
|
1775
|
-
const routeOptions = routeConfig.options;
|
|
1776
|
-
const route = createRoute(routeConfig, routeOptions, parent, router); // {
|
|
1777
|
-
// pendingMs: routeOptions.pendingMs ?? router.defaultPendingMs,
|
|
1778
|
-
// pendingMinMs: routeOptions.pendingMinMs ?? router.defaultPendingMinMs,
|
|
1779
|
-
// }
|
|
1780
|
-
|
|
1781
|
-
const existingRoute = router.routesById[route.routeId];
|
|
1782
|
-
|
|
1783
|
-
if (existingRoute) {
|
|
1784
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
1785
|
-
console.warn("Duplicate routes found with id: " + String(route.routeId), router.routesById, route);
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
throw new Error();
|
|
1789
|
-
}
|
|
1790
|
-
router.routesById[route.routeId] = route;
|
|
1791
|
-
const children = routeConfig.children;
|
|
1792
|
-
route.childRoutes = children != null && children.length ? recurseRoutes(children, route) : undefined;
|
|
1793
|
-
return route;
|
|
1794
|
-
});
|
|
1795
|
-
};
|
|
1796
|
-
|
|
1797
|
-
const routes = recurseRoutes([rootRouteConfig]);
|
|
1798
|
-
return routes[0];
|
|
1799
|
-
},
|
|
1800
|
-
parseLocation: (location, previousLocation) => {
|
|
1801
|
-
var _location$hash$split$;
|
|
1802
|
-
|
|
1803
|
-
const parsedSearch = router.options.parseSearch(location.search);
|
|
1804
|
-
return {
|
|
1805
|
-
pathname: location.pathname,
|
|
1806
|
-
searchStr: location.search,
|
|
1807
|
-
search: replaceEqualDeep(previousLocation == null ? void 0 : previousLocation.search, parsedSearch),
|
|
1808
|
-
hash: (_location$hash$split$ = location.hash.split('#').reverse()[0]) != null ? _location$hash$split$ : '',
|
|
1809
|
-
href: "" + location.pathname + location.search + location.hash,
|
|
1810
|
-
state: location.state,
|
|
1811
|
-
key: location.key
|
|
1812
|
-
};
|
|
1813
|
-
},
|
|
1814
|
-
buildLocation: function buildLocation(dest) {
|
|
1815
|
-
var _dest$from, _router$basepath, _dest$to, _last, _dest$params, _dest$__preSearchFilt, _functionalUpdate, _dest$__preSearchFilt2, _dest$__postSearchFil;
|
|
1816
|
-
|
|
1817
|
-
if (dest === void 0) {
|
|
1818
|
-
dest = {};
|
|
1819
|
-
}
|
|
1820
|
-
|
|
1821
|
-
// const resolvedFrom: Location = {
|
|
1822
|
-
// ...router.location,
|
|
1823
|
-
const fromPathname = dest.fromCurrent ? router.location.pathname : (_dest$from = dest.from) != null ? _dest$from : router.location.pathname;
|
|
1824
|
-
|
|
1825
|
-
let pathname = resolvePath((_router$basepath = router.basepath) != null ? _router$basepath : '/', fromPathname, "" + ((_dest$to = dest.to) != null ? _dest$to : '.'));
|
|
1826
|
-
|
|
1827
|
-
const fromMatches = router.matchRoutes(router.location.pathname, {
|
|
1828
|
-
strictParseParams: true
|
|
1829
|
-
});
|
|
1830
|
-
const toMatches = router.matchRoutes(pathname);
|
|
1831
|
-
|
|
1832
|
-
const prevParams = _extends({}, (_last = last(fromMatches)) == null ? void 0 : _last.params);
|
|
1833
|
-
|
|
1834
|
-
let nextParams = ((_dest$params = dest.params) != null ? _dest$params : true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
1835
|
-
|
|
1836
|
-
if (nextParams) {
|
|
1837
|
-
toMatches.map(d => d.options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
1838
|
-
Object.assign({}, nextParams, fn(nextParams));
|
|
1839
|
-
});
|
|
1840
|
-
}
|
|
1841
|
-
|
|
1842
|
-
pathname = interpolatePath(pathname, nextParams != null ? nextParams : {}); // Pre filters first
|
|
1843
|
-
|
|
1844
|
-
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
|
|
1845
|
-
|
|
1846
|
-
const destSearch = dest.search === true ? preFilteredSearch // Preserve resolvedFrom true
|
|
1847
|
-
: dest.search ? (_functionalUpdate = functionalUpdate(dest.search, preFilteredSearch)) != null ? _functionalUpdate : {} // Updater
|
|
1848
|
-
: (_dest$__preSearchFilt2 = dest.__preSearchFilters) != null && _dest$__preSearchFilt2.length ? preFilteredSearch // Preserve resolvedFrom filters
|
|
1849
|
-
: {}; // Then post filters
|
|
1850
|
-
|
|
1851
|
-
const postFilteredSearch = (_dest$__postSearchFil = dest.__postSearchFilters) != null && _dest$__postSearchFil.length ? dest.__postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
1852
|
-
const search = replaceEqualDeep(router.location.search, postFilteredSearch);
|
|
1853
|
-
const searchStr = router.options.stringifySearch(search);
|
|
1854
|
-
let hash = dest.hash === true ? router.location.hash : functionalUpdate(dest.hash, router.location.hash);
|
|
1855
|
-
hash = hash ? "#" + hash : '';
|
|
1856
|
-
return {
|
|
1857
|
-
pathname,
|
|
1858
|
-
search,
|
|
1859
|
-
searchStr,
|
|
1860
|
-
state: router.location.state,
|
|
1861
|
-
hash,
|
|
1862
|
-
href: "" + pathname + searchStr + hash,
|
|
1863
|
-
key: dest.key
|
|
1864
|
-
};
|
|
1865
|
-
},
|
|
1866
|
-
commitLocation: (next, replace) => {
|
|
1867
|
-
const id = '' + Date.now() + Math.random();
|
|
1868
|
-
if (router.navigateTimeout) clearTimeout(router.navigateTimeout);
|
|
1869
|
-
let nextAction = 'replace';
|
|
1870
|
-
|
|
1871
|
-
if (!replace) {
|
|
1872
|
-
nextAction = 'push';
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
const isSameUrl = router.parseLocation(history.location).href === next.href;
|
|
1876
|
-
|
|
1877
|
-
if (isSameUrl && !next.key) {
|
|
1878
|
-
nextAction = 'replace';
|
|
1879
|
-
}
|
|
1880
|
-
|
|
1881
|
-
if (nextAction === 'replace') {
|
|
1882
|
-
history.replace({
|
|
1883
|
-
pathname: next.pathname,
|
|
1884
|
-
hash: next.hash,
|
|
1885
|
-
search: next.searchStr
|
|
1886
|
-
}, {
|
|
1887
|
-
id
|
|
1888
|
-
});
|
|
1889
|
-
} else {
|
|
1890
|
-
history.push({
|
|
1891
|
-
pathname: next.pathname,
|
|
1892
|
-
hash: next.hash,
|
|
1893
|
-
search: next.searchStr
|
|
1894
|
-
}, {
|
|
1895
|
-
id
|
|
1896
|
-
});
|
|
1897
|
-
}
|
|
1898
|
-
|
|
1899
|
-
router.navigationPromise = new Promise(resolve => {
|
|
1900
|
-
const previousNavigationResolve = router.resolveNavigation;
|
|
1901
|
-
|
|
1902
|
-
router.resolveNavigation = () => {
|
|
1903
|
-
previousNavigationResolve();
|
|
1904
|
-
resolve();
|
|
1905
|
-
};
|
|
1906
|
-
});
|
|
1907
|
-
return router.navigationPromise;
|
|
1908
|
-
},
|
|
1909
|
-
buildNext: opts => {
|
|
1910
|
-
const next = router.buildLocation(opts);
|
|
1911
|
-
const matches = router.matchRoutes(next.pathname);
|
|
1912
|
-
|
|
1913
|
-
const __preSearchFilters = matches.map(match => {
|
|
1914
|
-
var _match$options$preSea;
|
|
1915
|
-
|
|
1916
|
-
return (_match$options$preSea = match.options.preSearchFilters) != null ? _match$options$preSea : [];
|
|
1917
|
-
}).flat().filter(Boolean);
|
|
1918
|
-
|
|
1919
|
-
const __postSearchFilters = matches.map(match => {
|
|
1920
|
-
var _match$options$postSe;
|
|
1921
|
-
|
|
1922
|
-
return (_match$options$postSe = match.options.postSearchFilters) != null ? _match$options$postSe : [];
|
|
1923
|
-
}).flat().filter(Boolean);
|
|
1924
|
-
|
|
1925
|
-
return router.buildLocation(_extends({}, opts, {
|
|
1926
|
-
__preSearchFilters,
|
|
1927
|
-
__postSearchFilters
|
|
1928
|
-
}));
|
|
1929
|
-
},
|
|
1930
1815
|
cancelMatches: () => {
|
|
1931
1816
|
var _router$state$pending, _router$state$pending2;
|
|
1932
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 => {
|
|
@@ -2029,6 +1914,7 @@ function createRouter(userOptions) {
|
|
|
2029
1914
|
params: d.params,
|
|
2030
1915
|
search: d.search
|
|
2031
1916
|
});
|
|
1917
|
+
delete router.matchCache[d.matchId];
|
|
2032
1918
|
});
|
|
2033
1919
|
|
|
2034
1920
|
if (matches.some(d => d.status === 'loading')) {
|
|
@@ -2188,32 +2074,11 @@ function createRouter(userOptions) {
|
|
|
2188
2074
|
return matches;
|
|
2189
2075
|
},
|
|
2190
2076
|
loadMatches: async (resolvedMatches, loaderOpts) => {
|
|
2191
|
-
const now = Date.now();
|
|
2192
|
-
const minMaxAge = loaderOpts != null && loaderOpts.preload ? Math.max(loaderOpts == null ? void 0 : loaderOpts.maxAge, loaderOpts == null ? void 0 : loaderOpts.gcMaxAge) : 0;
|
|
2193
2077
|
const matchPromises = resolvedMatches.map(async match => {
|
|
2194
2078
|
// Validate the match (loads search params etc)
|
|
2195
|
-
match.__.validate();
|
|
2079
|
+
match.__.validate();
|
|
2196
2080
|
|
|
2197
|
-
|
|
2198
|
-
if (loaderOpts != null && loaderOpts.preload && minMaxAge > 0) {
|
|
2199
|
-
// If the match is currently active, don't preload it
|
|
2200
|
-
if (router.state.matches.find(d => d.matchId === match.matchId)) {
|
|
2201
|
-
return;
|
|
2202
|
-
}
|
|
2203
|
-
|
|
2204
|
-
router.matchCache[match.matchId] = {
|
|
2205
|
-
gc: now + loaderOpts.gcMaxAge,
|
|
2206
|
-
match
|
|
2207
|
-
};
|
|
2208
|
-
} // If the match is invalid, errored or idle, trigger it to load
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
if (match.status === 'success' && match.getIsInvalid() || match.status === 'error' || match.status === 'idle') {
|
|
2212
|
-
const maxAge = loaderOpts != null && loaderOpts.preload ? loaderOpts == null ? void 0 : loaderOpts.maxAge : undefined;
|
|
2213
|
-
match.load({
|
|
2214
|
-
maxAge
|
|
2215
|
-
});
|
|
2216
|
-
}
|
|
2081
|
+
match.load(loaderOpts);
|
|
2217
2082
|
|
|
2218
2083
|
if (match.status === 'loading') {
|
|
2219
2084
|
// If requested, start the pending timers
|
|
@@ -2237,7 +2102,7 @@ function createRouter(userOptions) {
|
|
|
2237
2102
|
}
|
|
2238
2103
|
});
|
|
2239
2104
|
},
|
|
2240
|
-
reload: () => router.
|
|
2105
|
+
reload: () => router.__.navigate({
|
|
2241
2106
|
fromCurrent: true,
|
|
2242
2107
|
replace: true,
|
|
2243
2108
|
search: true
|
|
@@ -2270,10 +2135,6 @@ function createRouter(userOptions) {
|
|
|
2270
2135
|
to: next.pathname
|
|
2271
2136
|
}));
|
|
2272
2137
|
},
|
|
2273
|
-
_navigate: location => {
|
|
2274
|
-
const next = router.buildNext(location);
|
|
2275
|
-
return router.commitLocation(next, location.replace);
|
|
2276
|
-
},
|
|
2277
2138
|
navigate: async _ref8 => {
|
|
2278
2139
|
let {
|
|
2279
2140
|
from,
|
|
@@ -2297,7 +2158,7 @@ function createRouter(userOptions) {
|
|
|
2297
2158
|
} catch (e) {}
|
|
2298
2159
|
|
|
2299
2160
|
invariant(!isExternal, 'Attempting to navigate to external url with router.navigate!');
|
|
2300
|
-
return router.
|
|
2161
|
+
return router.__.navigate({
|
|
2301
2162
|
from: fromString,
|
|
2302
2163
|
to: toString,
|
|
2303
2164
|
search,
|
|
@@ -2369,7 +2230,7 @@ function createRouter(userOptions) {
|
|
|
2369
2230
|
} // All is well? Navigate!)
|
|
2370
2231
|
|
|
2371
2232
|
|
|
2372
|
-
router.
|
|
2233
|
+
router.__.navigate(nextOpts);
|
|
2373
2234
|
}
|
|
2374
2235
|
}; // The click handler
|
|
2375
2236
|
|
|
@@ -2420,9 +2281,174 @@ function createRouter(userOptions) {
|
|
|
2420
2281
|
isActive,
|
|
2421
2282
|
disabled
|
|
2422
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
|
+
}
|
|
2423
2449
|
}
|
|
2424
2450
|
};
|
|
2425
|
-
router.location = router.parseLocation(history.location);
|
|
2451
|
+
router.location = router.__.parseLocation(history.location);
|
|
2426
2452
|
router.state.location = router.location;
|
|
2427
2453
|
router.update(userOptions); // Allow frameworks to hook into the router creation
|
|
2428
2454
|
|