react-router 6.2.2 → 6.4.0-pre.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v6.2.2
2
+ * React Router v6.4.0-pre.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -9,254 +9,250 @@
9
9
  * @license MIT
10
10
  */
11
11
  (function (global, factory) {
12
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('history')) :
13
- typeof define === 'function' && define.amd ? define(['exports', 'react', 'history'], factory) :
14
- (global = global || self, factory(global.ReactRouter = {}, global.React, global.HistoryLibrary));
15
- }(this, (function (exports, React, history) { 'use strict';
16
-
17
- function invariant(cond, message) {
18
- if (!cond) throw new Error(message);
19
- }
20
-
21
- function warning(cond, message) {
22
- if (!cond) {
23
- // eslint-disable-next-line no-console
24
- if (typeof console !== "undefined") console.warn(message);
25
-
26
- try {
27
- // Welcome to debugging React Router!
28
- //
29
- // This error is thrown as a convenience so you can more easily
30
- // find the source for a warning that appears in the console by
31
- // enabling "pause on exceptions" in your JavaScript debugger.
32
- throw new Error(message); // eslint-disable-next-line no-empty
33
- } catch (e) {}
34
- }
35
- }
36
-
37
- const alreadyWarned = {};
38
-
39
- function warningOnce(key, cond, message) {
40
- if (!cond && !alreadyWarned[key]) {
41
- alreadyWarned[key] = true;
42
- warning(false, message) ;
43
- }
44
- } ///////////////////////////////////////////////////////////////////////////////
45
- // CONTEXT
46
- ///////////////////////////////////////////////////////////////////////////////
12
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@remix-run/router'), require('react')) :
13
+ typeof define === 'function' && define.amd ? define(['exports', '@remix-run/router', 'react'], factory) :
14
+ (global = global || self, factory(global.ReactRouter = {}, global.Router, global.React));
15
+ }(this, (function (exports, router, React) { 'use strict';
47
16
 
48
17
  /**
49
- * A Navigator is a "location changer"; it's how you get to different locations.
18
+ * Copyright (c) Facebook, Inc. and its affiliates.
50
19
  *
51
- * Every history instance conforms to the Navigator interface, but the
52
- * distinction is useful primarily when it comes to the low-level <Router> API
53
- * where both the location and a navigator must be provided separately in order
54
- * to avoid "tearing" that may occur in a suspense-enabled app if the action
55
- * and/or location were to be read directly from the history instance.
20
+ * This source code is licensed under the MIT license found in the
21
+ * LICENSE file in the root directory of this source tree.
22
+ */
23
+ /**
24
+ * inlined Object.is polyfill to avoid requiring consumers ship their own
25
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
56
26
  */
57
27
 
28
+ function isPolyfill(x, y) {
29
+ return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
30
+ ;
31
+ }
58
32
 
59
- const NavigationContext = /*#__PURE__*/React.createContext(null);
33
+ const is = typeof Object.is === "function" ? Object.is : isPolyfill; // Intentionally not using named imports because Rollup uses dynamic
34
+ // dispatch for CommonJS interop named imports.
35
+
36
+ const {
37
+ useState,
38
+ useEffect,
39
+ useLayoutEffect,
40
+ useDebugValue
41
+ } = React;
42
+ let didWarnOld18Alpha = false;
43
+ let didWarnUncachedGetSnapshot = false; // Disclaimer: This shim breaks many of the rules of React, and only works
44
+ // because of a very particular set of implementation details and assumptions
45
+ // -- change any one of them and it will break. The most important assumption
46
+ // is that updates are always synchronous, because concurrent rendering is
47
+ // only available in versions of React that also have a built-in
48
+ // useSyncExternalStore API. And we only use this shim when the built-in API
49
+ // does not exist.
50
+ //
51
+ // Do not assume that the clever hacks used by this hook also work in general.
52
+ // The point of this shim is to replace the need for hacks by other libraries.
53
+
54
+ function useSyncExternalStore(subscribe, getSnapshot, // Note: The shim does not use getServerSnapshot, because pre-18 versions of
55
+ // React do not expose a way to check if we're hydrating. So users of the shim
56
+ // will need to track that themselves and return the correct value
57
+ // from `getSnapshot`.
58
+ getServerSnapshot) {
59
+ {
60
+ if (!didWarnOld18Alpha) {
61
+ // @ts-expect-error
62
+ if (React.startTransition !== undefined) {
63
+ didWarnOld18Alpha = true;
64
+ console.error("You are using an outdated, pre-release alpha of React 18 that " + "does not support useSyncExternalStore. The " + "use-sync-external-store shim will not work correctly. Upgrade " + "to a newer pre-release.");
65
+ }
66
+ }
67
+ } // Read the current snapshot from the store on every render. Again, this
68
+ // breaks the rules of React, and only works here because of specific
69
+ // implementation details, most importantly that updates are
70
+ // always synchronous.
60
71
 
61
- {
62
- NavigationContext.displayName = "Navigation";
63
- }
64
72
 
65
- const LocationContext = /*#__PURE__*/React.createContext(null);
73
+ const value = getSnapshot();
66
74
 
67
- {
68
- LocationContext.displayName = "Location";
69
- }
75
+ {
76
+ if (!didWarnUncachedGetSnapshot) {
77
+ const cachedValue = getSnapshot();
70
78
 
71
- const RouteContext = /*#__PURE__*/React.createContext({
72
- outlet: null,
73
- matches: []
74
- });
79
+ if (!is(value, cachedValue)) {
80
+ console.error("The result of getSnapshot should be cached to avoid an infinite loop");
81
+ didWarnUncachedGetSnapshot = true;
82
+ }
83
+ }
84
+ } // Because updates are synchronous, we don't queue them. Instead we force a
85
+ // re-render whenever the subscribed state changes by updating an some
86
+ // arbitrary useState hook. Then, during render, we call getSnapshot to read
87
+ // the current value.
88
+ //
89
+ // Because we don't actually use the state returned by the useState hook, we
90
+ // can save a bit of memory by storing other stuff in that slot.
91
+ //
92
+ // To implement the early bailout, we need to track some things on a mutable
93
+ // object. Usually, we would put that in a useRef hook, but we can stash it in
94
+ // our useState hook instead.
95
+ //
96
+ // To force a re-render, we call forceUpdate({inst}). That works because the
97
+ // new object always fails an equality check.
98
+
99
+
100
+ const [{
101
+ inst
102
+ }, forceUpdate] = useState({
103
+ inst: {
104
+ value,
105
+ getSnapshot
106
+ }
107
+ }); // Track the latest getSnapshot function with a ref. This needs to be updated
108
+ // in the layout phase so we can access it during the tearing check that
109
+ // happens on subscribe.
110
+
111
+ useLayoutEffect(() => {
112
+ inst.value = value;
113
+ inst.getSnapshot = getSnapshot; // Whenever getSnapshot or subscribe changes, we need to check in the
114
+ // commit phase if there was an interleaved mutation. In concurrent mode
115
+ // this can happen all the time, but even in synchronous mode, an earlier
116
+ // effect may have mutated the store.
117
+
118
+ if (checkIfSnapshotChanged(inst)) {
119
+ // Force a re-render.
120
+ forceUpdate({
121
+ inst
122
+ });
123
+ } // eslint-disable-next-line react-hooks/exhaustive-deps
124
+
125
+ }, [subscribe, value, getSnapshot]);
126
+ useEffect(() => {
127
+ // Check for changes right before subscribing. Subsequent changes will be
128
+ // detected in the subscription handler.
129
+ if (checkIfSnapshotChanged(inst)) {
130
+ // Force a re-render.
131
+ forceUpdate({
132
+ inst
133
+ });
134
+ }
75
135
 
76
- {
77
- RouteContext.displayName = "Route";
78
- } ///////////////////////////////////////////////////////////////////////////////
79
- // COMPONENTS
80
- ///////////////////////////////////////////////////////////////////////////////
136
+ const handleStoreChange = () => {
137
+ // TODO: Because there is no cross-renderer API for batching updates, it's
138
+ // up to the consumer of this library to wrap their subscription event
139
+ // with unstable_batchedUpdates. Should we try to detect when this isn't
140
+ // the case and print a warning in development?
141
+ // The store changed. Check if the snapshot changed since the last time we
142
+ // read from the store.
143
+ if (checkIfSnapshotChanged(inst)) {
144
+ // Force a re-render.
145
+ forceUpdate({
146
+ inst
147
+ });
148
+ }
149
+ }; // Subscribe to the store and return a clean-up function.
81
150
 
82
151
 
83
- /**
84
- * A <Router> that stores all entries in memory.
85
- *
86
- * @see https://reactrouter.com/docs/en/v6/api#memoryrouter
87
- */
88
- function MemoryRouter(_ref) {
89
- let {
90
- basename,
91
- children,
92
- initialEntries,
93
- initialIndex
94
- } = _ref;
95
- let historyRef = React.useRef();
152
+ return subscribe(handleStoreChange); // eslint-disable-next-line react-hooks/exhaustive-deps
153
+ }, [subscribe]);
154
+ useDebugValue(value);
155
+ return value;
156
+ }
96
157
 
97
- if (historyRef.current == null) {
98
- historyRef.current = history.createMemoryHistory({
99
- initialEntries,
100
- initialIndex
101
- });
102
- }
158
+ function checkIfSnapshotChanged(inst) {
159
+ const latestGetSnapshot = inst.getSnapshot;
160
+ const prevValue = inst.value;
103
161
 
104
- let history$1 = historyRef.current;
105
- let [state, setState] = React.useState({
106
- action: history$1.action,
107
- location: history$1.location
108
- });
109
- React.useLayoutEffect(() => history$1.listen(setState), [history$1]);
110
- return /*#__PURE__*/React.createElement(Router, {
111
- basename: basename,
112
- children: children,
113
- location: state.location,
114
- navigationType: state.action,
115
- navigator: history$1
116
- });
162
+ try {
163
+ const nextValue = latestGetSnapshot();
164
+ return !is(prevValue, nextValue);
165
+ } catch (error) {
166
+ return true;
167
+ }
117
168
  }
118
169
 
119
170
  /**
120
- * Changes the current location.
171
+ * Copyright (c) Facebook, Inc. and its affiliates.
121
172
  *
122
- * Note: This API is mostly useful in React.Component subclasses that are not
123
- * able to use hooks. In functional components, we recommend you use the
124
- * `useNavigate` hook instead.
173
+ * This source code is licensed under the MIT license found in the
174
+ * LICENSE file in the root directory of this source tree.
125
175
  *
126
- * @see https://reactrouter.com/docs/en/v6/api#navigate
176
+ * @flow
127
177
  */
128
- function Navigate(_ref2) {
129
- let {
130
- to,
131
- replace,
132
- state
133
- } = _ref2;
134
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of
135
- // the router loaded. We can help them understand how to avoid that.
136
- "<Navigate> may be used only in the context of a <Router> component.") : void 0;
137
- warning(!React.useContext(NavigationContext).static, "<Navigate> must not be used on the initial render in a <StaticRouter>. " + "This is a no-op, but you should modify your code so the <Navigate> is " + "only ever rendered in response to some user interaction or state change.") ;
138
- let navigate = useNavigate();
139
- React.useEffect(() => {
140
- navigate(to, {
141
- replace,
142
- state
143
- });
144
- });
145
- return null;
178
+ function useSyncExternalStore$1(subscribe, getSnapshot, getServerSnapshot) {
179
+ // Note: The shim does not use getServerSnapshot, because pre-18 versions of
180
+ // React do not expose a way to check if we're hydrating. So users of the shim
181
+ // will need to track that themselves and return the correct value
182
+ // from `getSnapshot`.
183
+ return getSnapshot();
146
184
  }
147
185
 
148
186
  /**
149
- * Renders the child route's element, if there is one.
150
- *
151
- * @see https://reactrouter.com/docs/en/v6/api#outlet
187
+ * Inlined into the react-router repo since use-sync-external-store does not
188
+ * provide a UMD-compatible package, so we need this to be able to distribute
189
+ * UMD react-router bundles
152
190
  */
153
- function Outlet(props) {
154
- return useOutlet(props.context);
155
- }
191
+ const canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
192
+ const isServerEnvironment = !canUseDOM;
193
+ const shim = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore;
194
+ const useSyncExternalStore$2 = // @ts-expect-error
195
+ React.useSyncExternalStore !== undefined ? React.useSyncExternalStore : shim;
156
196
 
157
- /**
158
- * Declares an element that should be rendered at a certain URL path.
159
- *
160
- * @see https://reactrouter.com/docs/en/v6/api#route
161
- */
162
- function Route(_props) {
163
- invariant(false, "A <Route> is only ever to be used as the child of <Routes> element, " + "never rendered directly. Please wrap your <Route> in a <Routes>.") ;
197
+ // Contexts for data routers
198
+ const DataRouterContext = /*#__PURE__*/React.createContext(null);
199
+
200
+ {
201
+ DataRouterContext.displayName = "DataRouter";
164
202
  }
165
203
 
204
+ const DataRouterStateContext = /*#__PURE__*/React.createContext(null);
205
+
206
+ {
207
+ DataRouterStateContext.displayName = "DataRouterState";
208
+ }
166
209
  /**
167
- * Provides location context for the rest of the app.
168
- *
169
- * Note: You usually won't render a <Router> directly. Instead, you'll render a
170
- * router that is more specific to your environment such as a <BrowserRouter>
171
- * in web browsers or a <StaticRouter> for server rendering.
210
+ * A Navigator is a "location changer"; it's how you get to different locations.
172
211
  *
173
- * @see https://reactrouter.com/docs/en/v6/api#router
212
+ * Every history instance conforms to the Navigator interface, but the
213
+ * distinction is useful primarily when it comes to the low-level <Router> API
214
+ * where both the location and a navigator must be provided separately in order
215
+ * to avoid "tearing" that may occur in a suspense-enabled app if the action
216
+ * and/or location were to be read directly from the history instance.
174
217
  */
175
- function Router(_ref3) {
176
- let {
177
- basename: basenameProp = "/",
178
- children = null,
179
- location: locationProp,
180
- navigationType = history.Action.Pop,
181
- navigator,
182
- static: staticProp = false
183
- } = _ref3;
184
- !!useInRouterContext() ? invariant(false, "You cannot render a <Router> inside another <Router>." + " You should never have more than one in your app.") : void 0;
185
- let basename = normalizePathname(basenameProp);
186
- let navigationContext = React.useMemo(() => ({
187
- basename,
188
- navigator,
189
- static: staticProp
190
- }), [basename, navigator, staticProp]);
191
218
 
192
- if (typeof locationProp === "string") {
193
- locationProp = history.parsePath(locationProp);
194
- }
195
219
 
196
- let {
197
- pathname = "/",
198
- search = "",
199
- hash = "",
200
- state = null,
201
- key = "default"
202
- } = locationProp;
203
- let location = React.useMemo(() => {
204
- let trailingPathname = stripBasename(pathname, basename);
220
+ const NavigationContext = /*#__PURE__*/React.createContext(null);
205
221
 
206
- if (trailingPathname == null) {
207
- return null;
208
- }
222
+ {
223
+ NavigationContext.displayName = "Navigation";
224
+ }
209
225
 
210
- return {
211
- pathname: trailingPathname,
212
- search,
213
- hash,
214
- state,
215
- key
216
- };
217
- }, [basename, pathname, search, hash, state, key]);
218
- warning(location != null, "<Router basename=\"" + basename + "\"> is not able to match the URL " + ("\"" + pathname + search + hash + "\" because it does not start with the ") + "basename, so the <Router> won't render anything.") ;
226
+ const LocationContext = /*#__PURE__*/React.createContext(null);
219
227
 
220
- if (location == null) {
221
- return null;
222
- }
228
+ {
229
+ LocationContext.displayName = "Location";
230
+ }
223
231
 
224
- return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
225
- value: navigationContext
226
- }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
227
- children: children,
228
- value: {
229
- location,
230
- navigationType
231
- }
232
- }));
232
+ const RouteContext = /*#__PURE__*/React.createContext({
233
+ outlet: null,
234
+ matches: []
235
+ });
236
+
237
+ {
238
+ RouteContext.displayName = "Route";
233
239
  }
234
240
 
235
- /**
236
- * A container for a nested tree of <Route> elements that renders the branch
237
- * that best matches the current location.
238
- *
239
- * @see https://reactrouter.com/docs/en/v6/api#routes
240
- */
241
- function Routes(_ref4) {
242
- let {
243
- children,
244
- location
245
- } = _ref4;
246
- return useRoutes(createRoutesFromChildren(children), location);
247
- } ///////////////////////////////////////////////////////////////////////////////
248
- // HOOKS
249
- ///////////////////////////////////////////////////////////////////////////////
241
+ const RouteErrorContext = /*#__PURE__*/React.createContext(null);
242
+
243
+ {
244
+ RouteErrorContext.displayName = "RouteError";
245
+ }
250
246
 
251
247
  /**
252
248
  * Returns the full href for the given "to" value. This is useful for building
253
249
  * custom links that are also accessible and preserve right-click behavior.
254
250
  *
255
- * @see https://reactrouter.com/docs/en/v6/api#usehref
251
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-href
256
252
  */
257
253
 
258
254
  function useHref(to) {
259
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
255
+ !useInRouterContext() ? router.invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
260
256
  // router loaded. We can help them understand how to avoid that.
261
257
  "useHref() may be used only in the context of a <Router> component.") : void 0;
262
258
  let {
@@ -271,9 +267,9 @@
271
267
  let joinedPathname = pathname;
272
268
 
273
269
  if (basename !== "/") {
274
- let toPathname = getToPathname(to);
270
+ let toPathname = router.getToPathname(to);
275
271
  let endsWithSlash = toPathname != null && toPathname.endsWith("/");
276
- joinedPathname = pathname === "/" ? basename + (endsWithSlash ? "/" : "") : joinPaths([basename, pathname]);
272
+ joinedPathname = pathname === "/" ? basename + (endsWithSlash ? "/" : "") : router.joinPaths([basename, pathname]);
277
273
  }
278
274
 
279
275
  return navigator.createHref({
@@ -285,7 +281,7 @@
285
281
  /**
286
282
  * Returns true if this component is a descendant of a <Router>.
287
283
  *
288
- * @see https://reactrouter.com/docs/en/v6/api#useinroutercontext
284
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-in-router-context
289
285
  */
290
286
 
291
287
  function useInRouterContext() {
@@ -299,22 +295,22 @@
299
295
  * "routing" in your app, and we'd like to know what your use case is. We may
300
296
  * be able to provide something higher-level to better suit your needs.
301
297
  *
302
- * @see https://reactrouter.com/docs/en/v6/api#uselocation
298
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-location
303
299
  */
304
300
 
305
301
  function useLocation() {
306
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
302
+ !useInRouterContext() ? router.invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
307
303
  // router loaded. We can help them understand how to avoid that.
308
304
  "useLocation() may be used only in the context of a <Router> component.") : void 0;
309
305
  return React.useContext(LocationContext).location;
310
306
  }
311
-
312
307
  /**
313
308
  * Returns the current navigation action which describes how the router came to
314
309
  * the current location, either by a pop, push, or replace on the history stack.
315
310
  *
316
- * @see https://reactrouter.com/docs/en/v6/api#usenavigationtype
311
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-navigation-type
317
312
  */
313
+
318
314
  function useNavigationType() {
319
315
  return React.useContext(LocationContext).navigationType;
320
316
  }
@@ -323,17 +319,17 @@
323
319
  * This is useful for components that need to know "active" state, e.g.
324
320
  * <NavLink>.
325
321
  *
326
- * @see https://reactrouter.com/docs/en/v6/api#usematch
322
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-match
327
323
  */
328
324
 
329
325
  function useMatch(pattern) {
330
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
326
+ !useInRouterContext() ? router.invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
331
327
  // router loaded. We can help them understand how to avoid that.
332
328
  "useMatch() may be used only in the context of a <Router> component.") : void 0;
333
329
  let {
334
330
  pathname
335
331
  } = useLocation();
336
- return React.useMemo(() => matchPath(pattern, pathname), [pathname, pattern]);
332
+ return React.useMemo(() => router.matchPath(pattern, pathname), [pathname, pattern]);
337
333
  }
338
334
  /**
339
335
  * The interface for the navigate() function returned from useNavigate().
@@ -343,10 +339,10 @@
343
339
  * Returns an imperative method for changing the location. Used by <Link>s, but
344
340
  * may also be used by other elements to change the location.
345
341
  *
346
- * @see https://reactrouter.com/docs/en/v6/api#usenavigate
342
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-navigate
347
343
  */
348
344
  function useNavigate() {
349
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
345
+ !useInRouterContext() ? router.invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
350
346
  // router loaded. We can help them understand how to avoid that.
351
347
  "useNavigate() may be used only in the context of a <Router> component.") : void 0;
352
348
  let {
@@ -369,7 +365,7 @@
369
365
  options = {};
370
366
  }
371
367
 
372
- warning(activeRef.current, "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.") ;
368
+ router.warning(activeRef.current, "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.") ;
373
369
  if (!activeRef.current) return;
374
370
 
375
371
  if (typeof to === "number") {
@@ -377,10 +373,10 @@
377
373
  return;
378
374
  }
379
375
 
380
- let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname);
376
+ let path = router.resolveTo(to, JSON.parse(routePathnamesJson), locationPathname);
381
377
 
382
378
  if (basename !== "/") {
383
- path.pathname = joinPaths([basename, path.pathname]);
379
+ path.pathname = router.joinPaths([basename, path.pathname]);
384
380
  }
385
381
 
386
382
  (!!options.replace ? navigator.replace : navigator.push)(path, options.state);
@@ -391,7 +387,7 @@
391
387
  /**
392
388
  * Returns the context (if provided) for the child route at this level of the route
393
389
  * hierarchy.
394
- * @see https://reactrouter.com/docs/en/v6/api#useoutletcontext
390
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-outlet-context
395
391
  */
396
392
 
397
393
  function useOutletContext() {
@@ -401,7 +397,7 @@
401
397
  * Returns the element for the child route at this level of the route
402
398
  * hierarchy. Used internally by <Outlet> to render child routes.
403
399
  *
404
- * @see https://reactrouter.com/docs/en/v6/api#useoutlet
400
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-outlet
405
401
  */
406
402
 
407
403
  function useOutlet(context) {
@@ -419,7 +415,7 @@
419
415
  * Returns an object of key/value pairs of the dynamic params from the current
420
416
  * URL that were matched by the route path.
421
417
  *
422
- * @see https://reactrouter.com/docs/en/v6/api#useparams
418
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-params
423
419
  */
424
420
 
425
421
  function useParams() {
@@ -432,7 +428,7 @@
432
428
  /**
433
429
  * Resolves the pathname of the given `to` value against the current location.
434
430
  *
435
- * @see https://reactrouter.com/docs/en/v6/api#useresolvedpath
431
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-resolved-path
436
432
  */
437
433
 
438
434
  function useResolvedPath(to) {
@@ -443,7 +439,7 @@
443
439
  pathname: locationPathname
444
440
  } = useLocation();
445
441
  let routePathnamesJson = JSON.stringify(matches.map(match => match.pathnameBase));
446
- return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname), [to, routePathnamesJson, locationPathname]);
442
+ return React.useMemo(() => router.resolveTo(to, JSON.parse(routePathnamesJson), locationPathname), [to, routePathnamesJson, locationPathname]);
447
443
  }
448
444
  /**
449
445
  * Returns the element of the route that matched the current location, prepared
@@ -451,13 +447,14 @@
451
447
  * elements in the tree must render an <Outlet> to render their child route's
452
448
  * element.
453
449
  *
454
- * @see https://reactrouter.com/docs/en/v6/api#useroutes
450
+ * @see https://reactrouter.com/docs/en/v6/hooks/use-routes
455
451
  */
456
452
 
457
453
  function useRoutes(routes, locationArg) {
458
- !useInRouterContext() ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
454
+ !useInRouterContext() ? router.invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
459
455
  // router loaded. We can help them understand how to avoid that.
460
456
  "useRoutes() may be used only in the context of a <Router> component.") : void 0;
457
+ let dataRouterStateContext = React.useContext(DataRouterStateContext);
461
458
  let {
462
459
  matches: parentMatches
463
460
  } = React.useContext(RouteContext);
@@ -498,8 +495,8 @@
498
495
  if (locationArg) {
499
496
  var _parsedLocationArg$pa;
500
497
 
501
- let parsedLocationArg = typeof locationArg === "string" ? history.parsePath(locationArg) : locationArg;
502
- !(parentPathnameBase === "/" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? invariant(false, "When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, " + "the location pathname must begin with the portion of the URL pathname that was " + ("matched by all parent routes. The current pathname base is \"" + parentPathnameBase + "\" ") + ("but pathname \"" + parsedLocationArg.pathname + "\" was given in the `location` prop.")) : void 0;
498
+ let parsedLocationArg = typeof locationArg === "string" ? router.parsePath(locationArg) : locationArg;
499
+ !(parentPathnameBase === "/" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? router.invariant(false, "When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, " + "the location pathname must begin with the portion of the URL pathname that was " + ("matched by all parent routes. The current pathname base is \"" + parentPathnameBase + "\" ") + ("but pathname \"" + parsedLocationArg.pathname + "\" was given in the `location` prop.")) : void 0;
503
500
  location = parsedLocationArg;
504
501
  } else {
505
502
  location = locationFromContext;
@@ -507,511 +504,683 @@
507
504
 
508
505
  let pathname = location.pathname || "/";
509
506
  let remainingPathname = parentPathnameBase === "/" ? pathname : pathname.slice(parentPathnameBase.length) || "/";
510
- let matches = matchRoutes(routes, {
507
+ let matches = router.matchRoutes(routes, {
511
508
  pathname: remainingPathname
512
509
  });
513
510
 
514
511
  {
515
- warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") ;
516
- warning(matches == null || matches[matches.length - 1].route.element !== undefined, "Matched leaf route at location \"" + location.pathname + location.search + location.hash + "\" does not have an element. " + "This means it will render an <Outlet /> with a null value by default resulting in an \"empty\" page.") ;
512
+ router.warning(parentRoute || matches != null, "No routes matched location \"" + location.pathname + location.search + location.hash + "\" ") ;
513
+ router.warning(matches == null || matches[matches.length - 1].route.element !== undefined, "Matched leaf route at location \"" + location.pathname + location.search + location.hash + "\" does not have an element. " + "This means it will render an <Outlet /> with a null value by default resulting in an \"empty\" page.") ;
517
514
  }
518
515
 
519
516
  return _renderMatches(matches && matches.map(match => Object.assign({}, match, {
520
517
  params: Object.assign({}, parentParams, match.params),
521
- pathname: joinPaths([parentPathnameBase, match.pathname]),
522
- pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : joinPaths([parentPathnameBase, match.pathnameBase])
523
- })), parentMatches);
524
- } ///////////////////////////////////////////////////////////////////////////////
525
- // UTILS
526
- ///////////////////////////////////////////////////////////////////////////////
527
-
528
- /**
529
- * Creates a route config from a React "children" object, which is usually
530
- * either a `<Route>` element or an array of them. Used internally by
531
- * `<Routes>` to create a route config from its children.
532
- *
533
- * @see https://reactrouter.com/docs/en/v6/api#createroutesfromchildren
534
- */
518
+ pathname: router.joinPaths([parentPathnameBase, match.pathname]),
519
+ pathnameBase: match.pathnameBase === "/" ? parentPathnameBase : router.joinPaths([parentPathnameBase, match.pathnameBase])
520
+ })), parentMatches, dataRouterStateContext);
521
+ }
535
522
 
536
- function createRoutesFromChildren(children) {
537
- let routes = [];
538
- React.Children.forEach(children, element => {
539
- if (! /*#__PURE__*/React.isValidElement(element)) {
540
- // Ignore non-elements. This allows people to more easily inline
541
- // conditionals in their route config.
542
- return;
523
+ function DefaultErrorElement() {
524
+ let error = useRouteError();
525
+ let lightgrey = "rgba(200,200,200, 0.5)";
526
+ let preStyles = {
527
+ padding: "0.5rem",
528
+ backgroundColor: lightgrey
529
+ };
530
+ let codeStyles = {
531
+ padding: "2px 4px",
532
+ backgroundColor: lightgrey
533
+ };
534
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("h2", null, "Unhandled Thrown Error!"), /*#__PURE__*/React.createElement("p", {
535
+ style: {
536
+ fontStyle: "italic"
543
537
  }
538
+ }, (error == null ? void 0 : error.message) || error), error != null && error.stack ? /*#__PURE__*/React.createElement("pre", {
539
+ style: preStyles
540
+ }, error == null ? void 0 : error.stack) : null, /*#__PURE__*/React.createElement("p", null, "\uD83D\uDCBF Hey developer \uD83D\uDC4B"), /*#__PURE__*/React.createElement("p", null, "You can provide a way better UX than this when your app throws errors by providing your own\xA0", /*#__PURE__*/React.createElement("code", {
541
+ style: codeStyles
542
+ }, "errorElement"), " props on\xA0", /*#__PURE__*/React.createElement("code", {
543
+ style: codeStyles
544
+ }, "<Route>")));
545
+ }
544
546
 
545
- if (element.type === React.Fragment) {
546
- // Transparently support React.Fragment and its children.
547
- routes.push.apply(routes, createRoutesFromChildren(element.props.children));
548
- return;
549
- }
547
+ class RenderErrorBoundary extends React.Component {
548
+ constructor(props) {
549
+ super(props);
550
+ this.state = {
551
+ location: props.location,
552
+ error: props.error
553
+ };
554
+ }
550
555
 
551
- !(element.type === Route) ? invariant(false, "[" + (typeof element.type === "string" ? element.type : element.type.name) + "] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>") : void 0;
552
- let route = {
553
- caseSensitive: element.props.caseSensitive,
554
- element: element.props.element,
555
- index: element.props.index,
556
- path: element.props.path
556
+ static getDerivedStateFromError(error) {
557
+ return {
558
+ error: error
557
559
  };
560
+ }
558
561
 
559
- if (element.props.children) {
560
- route.children = createRoutesFromChildren(element.props.children);
561
- }
562
+ static getDerivedStateFromProps(props, state) {
563
+ // When we get into an error state, the user will likely click "back" to the
564
+ // previous page that didn't have an error. Because this wraps the entire
565
+ // application, that will have no effect--the error page continues to display.
566
+ // This gives us a mechanism to recover from the error when the location changes.
567
+ //
568
+ // Whether we're in an error state or not, we update the location in state
569
+ // so that when we are in an error state, it gets reset when a new location
570
+ // comes in and the user recovers from the error.
571
+ if (state.location !== props.location) {
572
+ return {
573
+ error: props.error,
574
+ location: props.location
575
+ };
576
+ } // If we're not changing locations, preserve the location but still surface
577
+ // any new errors that may come through. We retain the existing error, we do
578
+ // this because the error provided from the app state may be cleared without
579
+ // the location changing.
562
580
 
563
- routes.push(route);
564
- });
565
- return routes;
566
- }
567
- /**
568
- * The parameters that were parsed from the URL path.
569
- */
570
581
 
571
- /**
572
- * Returns a path with params interpolated.
573
- *
574
- * @see https://reactrouter.com/docs/en/v6/api#generatepath
575
- */
576
- function generatePath(path, params) {
577
- if (params === void 0) {
578
- params = {};
582
+ return {
583
+ error: props.error || state.error,
584
+ location: state.location
585
+ };
579
586
  }
580
587
 
581
- return path.replace(/:(\w+)/g, (_, key) => {
582
- !(params[key] != null) ? invariant(false, "Missing \":" + key + "\" param") : void 0;
583
- return params[key];
584
- }).replace(/\/*\*$/, _ => params["*"] == null ? "" : params["*"].replace(/^\/*/, "/"));
585
- }
586
- /**
587
- * A RouteMatch contains info about how a route matched a URL.
588
- */
589
-
590
- /**
591
- * Matches the given routes to a location and returns the match data.
592
- *
593
- * @see https://reactrouter.com/docs/en/v6/api#matchroutes
594
- */
595
- function matchRoutes(routes, locationArg, basename) {
596
- if (basename === void 0) {
597
- basename = "/";
588
+ componentDidCatch(error, errorInfo) {
589
+ console.error("React Router caught the following error during render", error, errorInfo);
598
590
  }
599
591
 
600
- let location = typeof locationArg === "string" ? history.parsePath(locationArg) : locationArg;
601
- let pathname = stripBasename(location.pathname || "/", basename);
602
-
603
- if (pathname == null) {
604
- return null;
592
+ render() {
593
+ return this.state.error ? /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {
594
+ value: this.state.error,
595
+ children: this.props.component
596
+ }) : this.props.children;
605
597
  }
606
598
 
607
- let branches = flattenRoutes(routes);
608
- rankRouteBranches(branches);
609
- let matches = null;
610
-
611
- for (let i = 0; matches == null && i < branches.length; ++i) {
612
- matches = matchRouteBranch(branches[i], pathname);
599
+ }
600
+ function _renderMatches(matches, parentMatches, dataRouterState) {
601
+ if (parentMatches === void 0) {
602
+ parentMatches = [];
613
603
  }
614
604
 
615
- return matches;
616
- }
605
+ if (matches == null) return null;
606
+ let renderedMatches = matches; // If we have data errors, trim matches to the highest error boundary
617
607
 
618
- function flattenRoutes(routes, branches, parentsMeta, parentPath) {
619
- if (branches === void 0) {
620
- branches = [];
621
- }
608
+ let errors = dataRouterState == null ? void 0 : dataRouterState.errors;
622
609
 
623
- if (parentsMeta === void 0) {
624
- parentsMeta = [];
610
+ if (errors != null) {
611
+ let errorIndex = renderedMatches.findIndex(m => m.route.id && (errors == null ? void 0 : errors[m.route.id]));
612
+ !(errorIndex >= 0) ? router.invariant(false, "Could not find a matching route for the current errors: " + errors) : void 0;
613
+ renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));
625
614
  }
626
615
 
627
- if (parentPath === void 0) {
628
- parentPath = "";
629
- }
630
-
631
- routes.forEach((route, index) => {
632
- let meta = {
633
- relativePath: route.path || "",
634
- caseSensitive: route.caseSensitive === true,
635
- childrenIndex: index,
636
- route
637
- };
638
-
639
- if (meta.relativePath.startsWith("/")) {
640
- !meta.relativePath.startsWith(parentPath) ? invariant(false, "Absolute route path \"" + meta.relativePath + "\" nested under path " + ("\"" + parentPath + "\" is not valid. An absolute child route path ") + "must start with the combined path of all its parent routes.") : void 0;
641
- meta.relativePath = meta.relativePath.slice(parentPath.length);
642
- }
616
+ return renderedMatches.reduceRight((outlet, match, index) => {
617
+ let error = match.route.id ? errors == null ? void 0 : errors[match.route.id] : null; // Only data routers handle errors
643
618
 
644
- let path = joinPaths([parentPath, meta.relativePath]);
645
- let routesMeta = parentsMeta.concat(meta); // Add the children before adding this route to the array so we traverse the
646
- // route tree depth-first and child routes appear before their parents in
647
- // the "flattened" version.
648
-
649
- if (route.children && route.children.length > 0) {
650
- !(route.index !== true) ? invariant(false, "Index routes must not have child routes. Please remove " + ("all child routes from route path \"" + path + "\".")) : void 0;
651
- flattenRoutes(route.children, branches, routesMeta, path);
652
- } // Routes without a path shouldn't ever match by themselves unless they are
653
- // index routes, so don't add them to the list of possible branches.
619
+ let errorElement = dataRouterState ? match.route.errorElement || /*#__PURE__*/React.createElement(DefaultErrorElement, null) : null;
654
620
 
621
+ let getChildren = () => /*#__PURE__*/React.createElement(RouteContext.Provider, {
622
+ children: error ? errorElement : match.route.element !== undefined ? match.route.element : outlet,
623
+ value: {
624
+ outlet,
625
+ matches: parentMatches.concat(renderedMatches.slice(0, index + 1))
626
+ }
627
+ }); // Only wrap in an error boundary within data router usages when we have an
628
+ // errorElement on this route. Otherwise let it bubble up to an ancestor
629
+ // errorElement
655
630
 
656
- if (route.path == null && !route.index) {
657
- return;
658
- }
659
631
 
660
- branches.push({
661
- path,
662
- score: computeScore(path, route.index),
663
- routesMeta
664
- });
665
- });
666
- return branches;
632
+ return dataRouterState && (match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {
633
+ location: dataRouterState.location,
634
+ component: errorElement,
635
+ error: error,
636
+ children: getChildren()
637
+ }) : getChildren();
638
+ }, null);
667
639
  }
668
-
669
- function rankRouteBranches(branches) {
670
- branches.sort((a, b) => a.score !== b.score ? b.score - a.score // Higher score first
671
- : compareIndexes(a.routesMeta.map(meta => meta.childrenIndex), b.routesMeta.map(meta => meta.childrenIndex)));
640
+ var DataRouterHook;
641
+
642
+ (function (DataRouterHook) {
643
+ DataRouterHook["UseLoaderData"] = "useLoaderData";
644
+ DataRouterHook["UseActionData"] = "useActionData";
645
+ DataRouterHook["UseRouteError"] = "useRouteError";
646
+ DataRouterHook["UseNavigation"] = "useNavigation";
647
+ DataRouterHook["UseRouteLoaderData"] = "useRouteLoaderData";
648
+ DataRouterHook["UseMatches"] = "useMatches";
649
+ DataRouterHook["UseRevalidator"] = "useRevalidator";
650
+ })(DataRouterHook || (DataRouterHook = {}));
651
+
652
+ function useDataRouterState(hookName) {
653
+ let state = React.useContext(DataRouterStateContext);
654
+ !state ? router.invariant(false, hookName + " must be used within a DataRouter") : void 0;
655
+ return state;
672
656
  }
657
+ /**
658
+ * Returns the current navigation, defaulting to an "idle" navigation when
659
+ * no navigation is in progress
660
+ */
673
661
 
674
- const paramRe = /^:\w+$/;
675
- const dynamicSegmentValue = 3;
676
- const indexRouteValue = 2;
677
- const emptySegmentValue = 1;
678
- const staticSegmentValue = 10;
679
- const splatPenalty = -2;
680
-
681
- const isSplat = s => s === "*";
682
-
683
- function computeScore(path, index) {
684
- let segments = path.split("/");
685
- let initialScore = segments.length;
686
-
687
- if (segments.some(isSplat)) {
688
- initialScore += splatPenalty;
689
- }
690
-
691
- if (index) {
692
- initialScore += indexRouteValue;
693
- }
694
662
 
695
- return segments.filter(s => !isSplat(s)).reduce((score, segment) => score + (paramRe.test(segment) ? dynamicSegmentValue : segment === "" ? emptySegmentValue : staticSegmentValue), initialScore);
663
+ function useNavigation() {
664
+ let state = useDataRouterState(DataRouterHook.UseNavigation);
665
+ return state.navigation;
696
666
  }
667
+ /**
668
+ * Returns a revalidate function for manually triggering revalidation, as well
669
+ * as the current state of any manual revalidations
670
+ */
697
671
 
698
- function compareIndexes(a, b) {
699
- let siblings = a.length === b.length && a.slice(0, -1).every((n, i) => n === b[i]);
700
- return siblings ? // If two routes are siblings, we should try to match the earlier sibling
701
- // first. This allows people to have fine-grained control over the matching
702
- // behavior by simply putting routes with identical paths in the order they
703
- // want them tried.
704
- a[a.length - 1] - b[b.length - 1] : // Otherwise, it doesn't really make sense to rank non-siblings by index,
705
- // so they sort equally.
706
- 0;
672
+ function useRevalidator() {
673
+ let router$1 = React.useContext(DataRouterContext);
674
+ !router$1 ? router.invariant(false, "useRevalidator must be used within a DataRouter") : void 0;
675
+ let state = useDataRouterState(DataRouterHook.UseRevalidator);
676
+ return {
677
+ revalidate: router$1.revalidate,
678
+ state: state.revalidation
679
+ };
707
680
  }
681
+ /**
682
+ * Returns the active route matches, useful for accessing loaderData for
683
+ * parent/child routes or the route "handle" property
684
+ */
708
685
 
709
- function matchRouteBranch(branch, pathname) {
686
+ function useMatches() {
710
687
  let {
711
- routesMeta
712
- } = branch;
713
- let matchedParams = {};
714
- let matchedPathname = "/";
715
- let matches = [];
716
-
717
- for (let i = 0; i < routesMeta.length; ++i) {
718
- let meta = routesMeta[i];
719
- let end = i === routesMeta.length - 1;
720
- let remainingPathname = matchedPathname === "/" ? pathname : pathname.slice(matchedPathname.length) || "/";
721
- let match = matchPath({
722
- path: meta.relativePath,
723
- caseSensitive: meta.caseSensitive,
724
- end
725
- }, remainingPathname);
726
- if (!match) return null;
727
- Object.assign(matchedParams, match.params);
728
- let route = meta.route;
729
- matches.push({
730
- params: matchedParams,
731
- pathname: joinPaths([matchedPathname, match.pathname]),
732
- pathnameBase: normalizePathname(joinPaths([matchedPathname, match.pathnameBase])),
733
- route
734
- });
688
+ matches,
689
+ loaderData
690
+ } = useDataRouterState(DataRouterHook.UseMatches);
691
+ return React.useMemo(() => matches.map(match => {
692
+ let {
693
+ pathname,
694
+ params
695
+ } = match;
696
+ return {
697
+ id: match.route.id,
698
+ pathname,
699
+ params,
700
+ data: loaderData[match.route.id],
701
+ handle: match.route.handle
702
+ };
703
+ }), [matches, loaderData]);
704
+ }
705
+ /**
706
+ * Returns the loader data for the nearest ancestor Route loader
707
+ */
735
708
 
736
- if (match.pathnameBase !== "/") {
737
- matchedPathname = joinPaths([matchedPathname, match.pathnameBase]);
738
- }
739
- }
709
+ function useLoaderData() {
710
+ var _state$loaderData;
740
711
 
741
- return matches;
712
+ let state = useDataRouterState(DataRouterHook.UseLoaderData);
713
+ let route = React.useContext(RouteContext);
714
+ !route ? router.invariant(false, "useLoaderData must be used inside a RouteContext") : void 0;
715
+ let thisRoute = route.matches[route.matches.length - 1];
716
+ !thisRoute.route.id ? router.invariant(false, useLoaderData + " can only be used on routes that contain a unique \"id\"") : void 0;
717
+ return (_state$loaderData = state.loaderData) == null ? void 0 : _state$loaderData[thisRoute.route.id];
742
718
  }
743
719
  /**
744
- * Renders the result of `matchRoutes()` into a React element.
720
+ * Returns the loaderData for the given routeId
745
721
  */
746
722
 
723
+ function useRouteLoaderData(routeId) {
724
+ var _state$loaderData2;
747
725
 
748
- function renderMatches(matches) {
749
- return _renderMatches(matches);
726
+ let state = useDataRouterState(DataRouterHook.UseRouteLoaderData);
727
+ return (_state$loaderData2 = state.loaderData) == null ? void 0 : _state$loaderData2[routeId];
750
728
  }
729
+ /**
730
+ * Returns the action data for the nearest ancestor Route action
731
+ */
751
732
 
752
- function _renderMatches(matches, parentMatches) {
753
- if (parentMatches === void 0) {
754
- parentMatches = [];
755
- }
756
-
757
- if (matches == null) return null;
758
- return matches.reduceRight((outlet, match, index) => {
759
- return /*#__PURE__*/React.createElement(RouteContext.Provider, {
760
- children: match.route.element !== undefined ? match.route.element : outlet,
761
- value: {
762
- outlet,
763
- matches: parentMatches.concat(matches.slice(0, index + 1))
764
- }
765
- });
766
- }, null);
733
+ function useActionData() {
734
+ let state = useDataRouterState(DataRouterHook.UseRouteError);
735
+ let route = React.useContext(RouteContext);
736
+ !route ? router.invariant(false, "useRouteError must be used inside a RouteContext") : void 0;
737
+ return Object.values((state == null ? void 0 : state.actionData) || {})[0];
767
738
  }
768
739
  /**
769
- * A PathPattern is used to match on some portion of a URL pathname.
740
+ * Returns the nearest ancestor Route error, which could be a loader/action
741
+ * error or a render error. This is intended to be called from your
742
+ * errorElement to display a proper error message.
770
743
  */
771
744
 
745
+ function useRouteError() {
746
+ var _state$errors;
772
747
 
773
- /**
774
- * Performs pattern matching on a URL pathname and returns information about
775
- * the match.
776
- *
777
- * @see https://reactrouter.com/docs/en/v6/api#matchpath
778
- */
779
- function matchPath(pattern, pathname) {
780
- if (typeof pattern === "string") {
781
- pattern = {
782
- path: pattern,
783
- caseSensitive: false,
784
- end: true
785
- };
748
+ let error = React.useContext(RouteErrorContext);
749
+ let state = useDataRouterState(DataRouterHook.UseRouteError);
750
+ let route = React.useContext(RouteContext);
751
+ let thisRoute = route.matches[route.matches.length - 1]; // If this was a render error, we put it in a RouteError context inside
752
+ // of RenderErrorBoundary
753
+
754
+ if (error) {
755
+ return error;
786
756
  }
787
757
 
788
- let [matcher, paramNames] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
789
- let match = pathname.match(matcher);
790
- if (!match) return null;
791
- let matchedPathname = match[0];
792
- let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
793
- let captureGroups = match.slice(1);
794
- let params = paramNames.reduce((memo, paramName, index) => {
795
- // We need to compute the pathnameBase here using the raw splat value
796
- // instead of using params["*"] later because it will be decoded then
797
- if (paramName === "*") {
798
- let splatValue = captureGroups[index] || "";
799
- pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
800
- }
758
+ !route ? router.invariant(false, "useRouteError must be used inside a RouteContext") : void 0;
759
+ !thisRoute.route.id ? router.invariant(false, "useRouteError can only be used on routes that contain a unique \"id\"") : void 0; // Otherwise look for errors from our data router state
801
760
 
802
- memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || "", paramName);
803
- return memo;
804
- }, {});
805
- return {
806
- params,
807
- pathname: matchedPathname,
808
- pathnameBase,
809
- pattern
810
- };
761
+ return (_state$errors = state.errors) == null ? void 0 : _state$errors[thisRoute.route.id];
811
762
  }
763
+ const alreadyWarned = {};
812
764
 
813
- function compilePath(path, caseSensitive, end) {
814
- if (caseSensitive === void 0) {
815
- caseSensitive = false;
765
+ function warningOnce(key, cond, message) {
766
+ if (!cond && !alreadyWarned[key]) {
767
+ alreadyWarned[key] = true;
768
+ router.warning(false, message) ;
816
769
  }
770
+ }
817
771
 
818
- if (end === void 0) {
819
- end = true;
820
- }
772
+ // to avoid issues w.r.t. dual initialization fetches in concurrent rendering.
773
+ // Data router apps are expected to have a static route tree and are not intended
774
+ // to be unmounted/remounted at runtime.
821
775
 
822
- warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\".")) ;
823
- let paramNames = [];
824
- let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below
825
- .replace(/^\/*/, "/") // Make sure it has a leading /
826
- .replace(/[\\.*+^$?{}|()[\]]/g, "\\$&") // Escape special regex chars
827
- .replace(/:(\w+)/g, (_, paramName) => {
828
- paramNames.push(paramName);
829
- return "([^\\/]+)";
830
- });
776
+ let routerSingleton;
777
+ /**
778
+ * @private
779
+ */
831
780
 
832
- if (path.endsWith("*")) {
833
- paramNames.push("*");
834
- regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest
835
- : "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"]
836
- } else {
837
- regexpSource += end ? "\\/*$" // When matching to the end, ignore trailing slashes
838
- : // Otherwise, match a word boundary or a proceeding /. The word boundary restricts
839
- // parent routes to matching only their own words and nothing more, e.g. parent
840
- // route "/home" should not match "/home2".
841
- // Additionally, allow paths starting with `.`, `-`, `~`, and url-encoded entities,
842
- // but do not consume the character in the matched path so they can match against
843
- // nested paths.
844
- "(?:(?=[.~-]|%[0-9A-F]{2})|\\b|\\/|$)";
781
+ function useRenderDataRouter(_ref) {
782
+ let {
783
+ children,
784
+ fallbackElement,
785
+ routes,
786
+ createRouter
787
+ } = _ref;
788
+
789
+ if (!routerSingleton) {
790
+ routerSingleton = createRouter(routes || createRoutesFromChildren(children)).initialize();
845
791
  }
846
792
 
847
- let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
848
- return [matcher, paramNames];
849
- }
793
+ let router = routerSingleton; // Sync router state to our component state to force re-renders
850
794
 
851
- function safelyDecodeURIComponent(value, paramName) {
852
- try {
853
- return decodeURIComponent(value);
854
- } catch (error) {
855
- warning(false, "The value for the URL param \"" + paramName + "\" will not be decoded because" + (" the string \"" + value + "\" is a malformed URL segment. This is probably") + (" due to a bad percent encoding (" + error + ").")) ;
856
- return value;
795
+ let state = useSyncExternalStore$2(router.subscribe, () => router.state);
796
+ let navigator = React.useMemo(() => {
797
+ return {
798
+ createHref: router.createHref,
799
+ go: n => router.navigate(n),
800
+ push: (to, state) => router.navigate(to, {
801
+ state
802
+ }),
803
+ replace: (to, state) => router.navigate(to, {
804
+ replace: true,
805
+ state
806
+ })
807
+ };
808
+ }, [router]);
809
+
810
+ if (!state.initialized) {
811
+ return fallbackElement || null;
857
812
  }
813
+
814
+ return /*#__PURE__*/React.createElement(DataRouterContext.Provider, {
815
+ value: router
816
+ }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, {
817
+ value: state
818
+ }, /*#__PURE__*/React.createElement(Router, {
819
+ location: state.location,
820
+ navigationType: state.historyAction,
821
+ navigator: navigator
822
+ }, /*#__PURE__*/React.createElement(DataRoutes, {
823
+ routes: routes,
824
+ children: children
825
+ }))));
826
+ }
827
+ function DataMemoryRouter(_ref2) {
828
+ let {
829
+ children,
830
+ initialEntries,
831
+ initialIndex,
832
+ hydrationData,
833
+ fallbackElement,
834
+ routes
835
+ } = _ref2;
836
+ return useRenderDataRouter({
837
+ children,
838
+ fallbackElement,
839
+ routes,
840
+ createRouter: routes => router.createMemoryRouter({
841
+ initialEntries,
842
+ initialIndex,
843
+ routes,
844
+ hydrationData
845
+ })
846
+ });
858
847
  }
848
+
859
849
  /**
860
- * Returns a resolved path object relative to the given pathname.
850
+ * A <Router> that stores all entries in memory.
861
851
  *
862
- * @see https://reactrouter.com/docs/en/v6/api#resolvepath
852
+ * @see https://reactrouter.com/docs/en/v6/routers/memory-router
863
853
  */
854
+ function MemoryRouter(_ref3) {
855
+ let {
856
+ basename,
857
+ children,
858
+ initialEntries,
859
+ initialIndex
860
+ } = _ref3;
861
+ let historyRef = React.useRef();
864
862
 
865
-
866
- function resolvePath(to, fromPathname) {
867
- if (fromPathname === void 0) {
868
- fromPathname = "/";
863
+ if (historyRef.current == null) {
864
+ historyRef.current = router.createMemoryHistory({
865
+ initialEntries,
866
+ initialIndex,
867
+ v5Compat: true
868
+ });
869
869
  }
870
870
 
871
- let {
872
- pathname: toPathname,
873
- search = "",
874
- hash = ""
875
- } = typeof to === "string" ? history.parsePath(to) : to;
876
- let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname;
877
- return {
878
- pathname,
879
- search: normalizeSearch(search),
880
- hash: normalizeHash(hash)
881
- };
871
+ let history = historyRef.current;
872
+ let [state, setState] = React.useState({
873
+ action: history.action,
874
+ location: history.location
875
+ });
876
+ React.useLayoutEffect(() => history.listen(setState), [history]);
877
+ return /*#__PURE__*/React.createElement(Router, {
878
+ basename: basename,
879
+ children: children,
880
+ location: state.location,
881
+ navigationType: state.action,
882
+ navigator: history
883
+ });
882
884
  }
883
885
 
884
- function resolvePathname(relativePath, fromPathname) {
885
- let segments = fromPathname.replace(/\/+$/, "").split("/");
886
- let relativeSegments = relativePath.split("/");
887
- relativeSegments.forEach(segment => {
888
- if (segment === "..") {
889
- // Keep the root "" segment so the pathname starts at /
890
- if (segments.length > 1) segments.pop();
891
- } else if (segment !== ".") {
892
- segments.push(segment);
893
- }
886
+ /**
887
+ * Changes the current location.
888
+ *
889
+ * Note: This API is mostly useful in React.Component subclasses that are not
890
+ * able to use hooks. In functional components, we recommend you use the
891
+ * `useNavigate` hook instead.
892
+ *
893
+ * @see https://reactrouter.com/docs/en/v6/components/navigate
894
+ */
895
+ function Navigate(_ref4) {
896
+ let {
897
+ to,
898
+ replace,
899
+ state
900
+ } = _ref4;
901
+ !useInRouterContext() ? router.invariant(false, // TODO: This error is probably because they somehow have 2 versions of
902
+ // the router loaded. We can help them understand how to avoid that.
903
+ "<Navigate> may be used only in the context of a <Router> component.") : void 0;
904
+ router.warning(!React.useContext(NavigationContext).static, "<Navigate> must not be used on the initial render in a <StaticRouter>. " + "This is a no-op, but you should modify your code so the <Navigate> is " + "only ever rendered in response to some user interaction or state change.") ;
905
+ let navigate = useNavigate();
906
+ React.useEffect(() => {
907
+ navigate(to, {
908
+ replace,
909
+ state
910
+ });
894
911
  });
895
- return segments.length > 1 ? segments.join("/") : "/";
912
+ return null;
896
913
  }
897
914
 
898
- function resolveTo(toArg, routePathnames, locationPathname) {
899
- let to = typeof toArg === "string" ? history.parsePath(toArg) : toArg;
900
- let toPathname = toArg === "" || to.pathname === "" ? "/" : to.pathname; // If a pathname is explicitly provided in `to`, it should be relative to the
901
- // route context. This is explained in `Note on `<Link to>` values` in our
902
- // migration guide from v5 as a means of disambiguation between `to` values
903
- // that begin with `/` and those that do not. However, this is problematic for
904
- // `to` values that do not provide a pathname. `to` can simply be a search or
905
- // hash string, in which case we should assume that the navigation is relative
906
- // to the current location's pathname and *not* the route pathname.
907
-
908
- let from;
909
-
910
- if (toPathname == null) {
911
- from = locationPathname;
912
- } else {
913
- let routePathnameIndex = routePathnames.length - 1;
915
+ /**
916
+ * Renders the child route's element, if there is one.
917
+ *
918
+ * @see https://reactrouter.com/docs/en/v6/components/outlet
919
+ */
920
+ function Outlet(props) {
921
+ return useOutlet(props.context);
922
+ }
914
923
 
915
- if (toPathname.startsWith("..")) {
916
- let toSegments = toPathname.split("/"); // Each leading .. segment means "go up one route" instead of "go up one
917
- // URL segment". This is a key difference from how <a href> works and a
918
- // major reason we call this a "to" value instead of a "href".
924
+ /**
925
+ * Declares an element that should be rendered at a certain URL path.
926
+ *
927
+ * @see https://reactrouter.com/docs/en/v6/components/route
928
+ */
929
+ function Route(_props) {
930
+ router.invariant(false, "A <Route> is only ever to be used as the child of <Routes> element, " + "never rendered directly. Please wrap your <Route> in a <Routes>.") ;
931
+ }
919
932
 
920
- while (toSegments[0] === "..") {
921
- toSegments.shift();
922
- routePathnameIndex -= 1;
923
- }
933
+ /**
934
+ * Provides location context for the rest of the app.
935
+ *
936
+ * Note: You usually won't render a <Router> directly. Instead, you'll render a
937
+ * router that is more specific to your environment such as a <BrowserRouter>
938
+ * in web browsers or a <StaticRouter> for server rendering.
939
+ *
940
+ * @see https://reactrouter.com/docs/en/v6/routers/router
941
+ */
942
+ function Router(_ref5) {
943
+ let {
944
+ basename: basenameProp = "/",
945
+ children = null,
946
+ location: locationProp,
947
+ navigationType = router.Action.Pop,
948
+ navigator,
949
+ static: staticProp = false
950
+ } = _ref5;
951
+ !!useInRouterContext() ? router.invariant(false, "You cannot render a <Router> inside another <Router>." + " You should never have more than one in your app.") : void 0;
952
+ let basename = router.normalizePathname(basenameProp);
953
+ let navigationContext = React.useMemo(() => ({
954
+ basename,
955
+ navigator,
956
+ static: staticProp
957
+ }), [basename, navigator, staticProp]);
924
958
 
925
- to.pathname = toSegments.join("/");
926
- } // If there are more ".." segments than parent routes, resolve relative to
927
- // the root / URL.
959
+ if (typeof locationProp === "string") {
960
+ locationProp = router.parsePath(locationProp);
961
+ }
928
962
 
963
+ let {
964
+ pathname = "/",
965
+ search = "",
966
+ hash = "",
967
+ state = null,
968
+ key = "default"
969
+ } = locationProp;
970
+ let location = React.useMemo(() => {
971
+ let trailingPathname = router.stripBasename(pathname, basename);
929
972
 
930
- from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
931
- }
973
+ if (trailingPathname == null) {
974
+ return null;
975
+ }
932
976
 
933
- let path = resolvePath(to, from); // Ensure the pathname has a trailing slash if the original to value had one.
977
+ return {
978
+ pathname: trailingPathname,
979
+ search,
980
+ hash,
981
+ state,
982
+ key
983
+ };
984
+ }, [basename, pathname, search, hash, state, key]);
985
+ router.warning(location != null, "<Router basename=\"" + basename + "\"> is not able to match the URL " + ("\"" + pathname + search + hash + "\" because it does not start with the ") + "basename, so the <Router> won't render anything.") ;
934
986
 
935
- if (toPathname && toPathname !== "/" && toPathname.endsWith("/") && !path.pathname.endsWith("/")) {
936
- path.pathname += "/";
987
+ if (location == null) {
988
+ return null;
937
989
  }
938
990
 
939
- return path;
991
+ return /*#__PURE__*/React.createElement(NavigationContext.Provider, {
992
+ value: navigationContext
993
+ }, /*#__PURE__*/React.createElement(LocationContext.Provider, {
994
+ children: children,
995
+ value: {
996
+ location,
997
+ navigationType
998
+ }
999
+ }));
940
1000
  }
941
1001
 
942
- function getToPathname(to) {
943
- // Empty strings should be treated the same as / paths
944
- return to === "" || to.pathname === "" ? "/" : typeof to === "string" ? history.parsePath(to).pathname : to.pathname;
1002
+ /**
1003
+ * A container for a nested tree of <Route> elements that renders the branch
1004
+ * that best matches the current location.
1005
+ *
1006
+ * @see https://reactrouter.com/docs/en/v6/components/routes
1007
+ */
1008
+ function Routes(_ref6) {
1009
+ let {
1010
+ children,
1011
+ location
1012
+ } = _ref6;
1013
+ return useRoutes(createRoutesFromChildren(children), location);
945
1014
  }
946
1015
 
947
- function stripBasename(pathname, basename) {
948
- if (basename === "/") return pathname;
1016
+ /**
1017
+ * @private
1018
+ * Used as an extension to <Routes> and accepts a manual `routes` array to be
1019
+ * instead of using JSX children. Extracted to it's own component to avoid
1020
+ * conditional usage of `useRoutes` if we have to render a `fallbackElement`
1021
+ */
1022
+ function DataRoutes(_ref7) {
1023
+ let {
1024
+ children,
1025
+ location,
1026
+ routes
1027
+ } = _ref7;
1028
+ return useRoutes(routes || createRoutesFromChildren(children), location);
1029
+ } ///////////////////////////////////////////////////////////////////////////////
1030
+ // UTILS
1031
+ ///////////////////////////////////////////////////////////////////////////////
949
1032
 
950
- if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
951
- return null;
952
- }
1033
+ /**
1034
+ * Creates a route config from a React "children" object, which is usually
1035
+ * either a `<Route>` element or an array of them. Used internally by
1036
+ * `<Routes>` to create a route config from its children.
1037
+ *
1038
+ * @see https://reactrouter.com/docs/en/v6/utils/create-routes-from-children
1039
+ */
953
1040
 
954
- let nextChar = pathname.charAt(basename.length);
955
1041
 
956
- if (nextChar && nextChar !== "/") {
957
- // pathname does not start with basename/
958
- return null;
1042
+ function createRoutesFromChildren(children, parentPath) {
1043
+ if (parentPath === void 0) {
1044
+ parentPath = [];
959
1045
  }
960
1046
 
961
- return pathname.slice(basename.length) || "/";
962
- }
1047
+ let routes = [];
1048
+ React.Children.forEach(children, (element, index) => {
1049
+ if (! /*#__PURE__*/React.isValidElement(element)) {
1050
+ // Ignore non-elements. This allows people to more easily inline
1051
+ // conditionals in their route config.
1052
+ return;
1053
+ }
963
1054
 
964
- const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/");
1055
+ if (element.type === React.Fragment) {
1056
+ // Transparently support React.Fragment and its children.
1057
+ routes.push.apply(routes, createRoutesFromChildren(element.props.children, parentPath));
1058
+ return;
1059
+ }
965
1060
 
966
- const normalizePathname = pathname => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
1061
+ !(element.type === Route) ? router.invariant(false, "[" + (typeof element.type === "string" ? element.type : element.type.name) + "] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>") : void 0;
1062
+ let treePath = [...parentPath, index];
1063
+ let route = {
1064
+ id: element.props.id || treePath.join("-"),
1065
+ caseSensitive: element.props.caseSensitive,
1066
+ element: element.props.element,
1067
+ index: element.props.index,
1068
+ path: element.props.path,
1069
+ loader: element.props.loader,
1070
+ action: element.props.action,
1071
+ errorElement: element.props.errorElement,
1072
+ shouldRevalidate: element.props.shouldRevalidate,
1073
+ handle: element.props.handle
1074
+ };
967
1075
 
968
- const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
1076
+ if (element.props.children) {
1077
+ route.children = createRoutesFromChildren(element.props.children, treePath);
1078
+ }
969
1079
 
970
- const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash; ///////////////////////////////////////////////////////////////////////////////
1080
+ routes.push(route);
1081
+ });
1082
+ return routes;
1083
+ }
1084
+ /**
1085
+ * Renders the result of `matchRoutes()` into a React element.
1086
+ */
1087
+
1088
+ function renderMatches(matches, dataRouterState) {
1089
+ return _renderMatches(matches, undefined, dataRouterState);
1090
+ }
971
1091
 
972
1092
  Object.defineProperty(exports, 'NavigationType', {
973
1093
  enumerable: true,
974
1094
  get: function () {
975
- return history.Action;
1095
+ return router.Action;
976
1096
  }
977
1097
  });
978
1098
  Object.defineProperty(exports, 'createPath', {
979
1099
  enumerable: true,
980
1100
  get: function () {
981
- return history.createPath;
1101
+ return router.createPath;
1102
+ }
1103
+ });
1104
+ Object.defineProperty(exports, 'generatePath', {
1105
+ enumerable: true,
1106
+ get: function () {
1107
+ return router.generatePath;
1108
+ }
1109
+ });
1110
+ Object.defineProperty(exports, 'isRouteErrorResponse', {
1111
+ enumerable: true,
1112
+ get: function () {
1113
+ return router.isRouteErrorResponse;
1114
+ }
1115
+ });
1116
+ Object.defineProperty(exports, 'json', {
1117
+ enumerable: true,
1118
+ get: function () {
1119
+ return router.json;
1120
+ }
1121
+ });
1122
+ Object.defineProperty(exports, 'matchPath', {
1123
+ enumerable: true,
1124
+ get: function () {
1125
+ return router.matchPath;
1126
+ }
1127
+ });
1128
+ Object.defineProperty(exports, 'matchRoutes', {
1129
+ enumerable: true,
1130
+ get: function () {
1131
+ return router.matchRoutes;
982
1132
  }
983
1133
  });
984
1134
  Object.defineProperty(exports, 'parsePath', {
985
1135
  enumerable: true,
986
1136
  get: function () {
987
- return history.parsePath;
1137
+ return router.parsePath;
1138
+ }
1139
+ });
1140
+ Object.defineProperty(exports, 'redirect', {
1141
+ enumerable: true,
1142
+ get: function () {
1143
+ return router.redirect;
1144
+ }
1145
+ });
1146
+ Object.defineProperty(exports, 'resolvePath', {
1147
+ enumerable: true,
1148
+ get: function () {
1149
+ return router.resolvePath;
988
1150
  }
989
1151
  });
1152
+ exports.DataMemoryRouter = DataMemoryRouter;
990
1153
  exports.MemoryRouter = MemoryRouter;
991
1154
  exports.Navigate = Navigate;
992
1155
  exports.Outlet = Outlet;
993
1156
  exports.Route = Route;
994
1157
  exports.Router = Router;
995
1158
  exports.Routes = Routes;
1159
+ exports.UNSAFE_DataRouterContext = DataRouterContext;
1160
+ exports.UNSAFE_DataRouterStateContext = DataRouterStateContext;
996
1161
  exports.UNSAFE_LocationContext = LocationContext;
997
1162
  exports.UNSAFE_NavigationContext = NavigationContext;
998
1163
  exports.UNSAFE_RouteContext = RouteContext;
999
1164
  exports.createRoutesFromChildren = createRoutesFromChildren;
1000
- exports.generatePath = generatePath;
1001
- exports.matchPath = matchPath;
1002
- exports.matchRoutes = matchRoutes;
1003
1165
  exports.renderMatches = renderMatches;
1004
- exports.resolvePath = resolvePath;
1166
+ exports.useActionData = useActionData;
1005
1167
  exports.useHref = useHref;
1006
1168
  exports.useInRouterContext = useInRouterContext;
1169
+ exports.useLoaderData = useLoaderData;
1007
1170
  exports.useLocation = useLocation;
1008
1171
  exports.useMatch = useMatch;
1172
+ exports.useMatches = useMatches;
1009
1173
  exports.useNavigate = useNavigate;
1174
+ exports.useNavigation = useNavigation;
1010
1175
  exports.useNavigationType = useNavigationType;
1011
1176
  exports.useOutlet = useOutlet;
1012
1177
  exports.useOutletContext = useOutletContext;
1013
1178
  exports.useParams = useParams;
1179
+ exports.useRenderDataRouter = useRenderDataRouter;
1014
1180
  exports.useResolvedPath = useResolvedPath;
1181
+ exports.useRevalidator = useRevalidator;
1182
+ exports.useRouteError = useRouteError;
1183
+ exports.useRouteLoaderData = useRouteLoaderData;
1015
1184
  exports.useRoutes = useRoutes;
1016
1185
 
1017
1186
  Object.defineProperty(exports, '__esModule', { value: true });