@remix-run/router
Advanced tools
Comparing version 0.2.0-pre.10 to 1.0.0
176
CHANGELOG.md
# @remix-run/router | ||
## 0.2.0-pre.10 | ||
## 1.0.0 | ||
### Patch Changes | ||
This is the first stable release of `@remix-run/router`, which provides all the underlying routing and data loading/mutation logic for `react-router`. You should _not_ be using this package directly unless you are authoring a routing library similar to `react-router`. | ||
- fix: remove internal router singleton (#9227) | ||
- fix: Avoid suspense loops on promise aborted values (#9226) | ||
For an overview of the features provided by `react-router`, we recommend you go check out the [docs][rr-docs], especially the [feature overview][rr-feature-overview] and the [tutorial][rr-tutorial]. | ||
## 0.2.0-pre.9 | ||
For an overview of the features provided by `@remix-run/router`, please check out the [README][remix-router-readme]. | ||
### Patch Changes | ||
- fix: rename resetScroll -> preventScrollReset (#9199) | ||
- fix: Await should fallback on route params navigations (#9181) | ||
- fix: proxy defer resolve/reject values through tracked promises (#9200) | ||
## 0.2.0-pre.8 | ||
### Patch Changes | ||
- fix: avoid uneccesary re-renders on `defer` resolution (#9155) | ||
- fix: pass `useMatches` objects to `ScrollRestoration` `getKey` (#9157) | ||
- fix: fetcher submission revalidating fetchers using wrong key (#9166) | ||
- fix: use a push navigation on submission errors (#9162) | ||
## 0.2.0-pre.7 | ||
### Patch Changes | ||
- fix: fix default redirect push/replace behavior (#9117) | ||
## 0.2.0-pre.6 | ||
### Patch Changes | ||
- fix: Rename `<Deferred>` to `<Await>` (#9095) | ||
- We are no longer replacing the `Promise` on `loaderData` with the value/error | ||
when it settles so it's now always a `Promise`. | ||
- To that end, we changed from `<Deferred value={promise}>` to | ||
`<Await resolve={promise}>` for clarity, and it also now supports using | ||
`<Await>` with raw promises from anywhere, not only those on `loaderData` | ||
from a defer() call. | ||
- Note that raw promises will not be automatically cancelled on interruptions | ||
so they are not recommended | ||
- The hooks are now `useAsyncValue`/`useAsyncError` | ||
## 0.2.0-pre.5 | ||
### Patch Changes | ||
- feat: Deferred API Updates (#9070) | ||
- Support array and single promise usages | ||
- `return defer([ await critical(), lazy() ])` | ||
- `return defer(lazy())` | ||
- Remove `Deferrable`/`ResolvedDeferrable` in favor of raw `Promise`'s and `Awaited` | ||
- Remove generics from `useAsyncValue` until `useLoaderData` generic is decided in 6.5 | ||
- feat: Add `createStaticRouter` for `@remix-run/router` SSR usage (#9013) | ||
**Notable changes:** | ||
- `request` is now the driving force inside the router utils, so that we can better handle `Request` instances coming form the server (as opposed to `string` and `Path` instances coming from the client) | ||
- Removed the `signal` param from `loader` and `action` functions in favor of `request.signal` | ||
**Example usage (Document Requests):** | ||
```jsx | ||
// Create a static handler | ||
let { query } = unstable_createStaticHandler(routes); | ||
// Perform a full-document query for the incoming Fetch Request. This will | ||
// execute the appropriate action/loaders and return either the state or a | ||
// Fetch Response in the case of redirects. | ||
let state = await query(fetchRequest); | ||
// If we received a Fetch Response back, let our server runtime handle directly | ||
if (state instanceof Response) { | ||
throw state; | ||
} | ||
// Otherwise, render our application providing the data routes and state | ||
let html = ReactDOMServer.renderToString( | ||
<React.StrictMode> | ||
<DataStaticRouter routes={routes} state={state} /> | ||
</React.StrictMode> | ||
); | ||
``` | ||
**Example usage (Data Requests):** | ||
```jsx | ||
// Create a static route handler | ||
let { queryRoute } = unstable_createStaticHandler(routes); | ||
// Perform a single-route query for the incoming Fetch Request. This will | ||
// execute the appropriate singular action/loader and return either the raw | ||
// data or a Fetch Response | ||
let data = await queryRoute(fetchRequest); | ||
// If we received a Fetch Response back, return it directly | ||
if (data instanceof Response) { | ||
return data; | ||
} | ||
// Otherwise, construct a Response from the raw data (assuming json here) | ||
return new Response(JSON.stringify(data), { | ||
headers: { | ||
"Content-Type": "application/json; charset=utf-8", | ||
}, | ||
}); | ||
``` | ||
- feat: SSR Updates for React Router (#9058) | ||
_Note: The Data-Router SSR aspects of `@remix-run/router` and `react-router-dom` are being released as **unstable** in this release (`unstable_createStaticHandler` and `unstable_DataStaticRouter`), and we plan to finalize them in a subsequent minor release once the kinks can be worked out with the Remix integration. To that end, they are available for use, but are subject to breaking changes in the next minor release._ | ||
- Remove `useRenderDataRouter()` in favor of `<DataRouterProvider>`/`<DataRouter>` | ||
- Support automatic hydration in `<DataStaticRouter>`/`<DataBrowserRouter>`/`<DataHashRouter>` | ||
- Uses `window.__staticRouterHydrationData` | ||
- Can be disabled on the server via `<DataStaticRouter hydrate={false}>` | ||
- Can be disabled (or overridden) in the browser by passing `hydrationData` to `<DataBrowserRouter>`/`<DataHashRouter>` | ||
- `<DataStaticRouter>` now tracks it's own SSR error boundaries on `StaticHandlerContext` | ||
- `StaticHandlerContext` now exposes `statusCode`/`loaderHeaders`/`actionHeaders` | ||
- `foundMissingHydrationData` check removed since Remix routes may have loaders (for modules) that don't return data for `loaderData` | ||
## 0.2.0-pre.4 | ||
### Patch Changes | ||
- fix: Handle fetcher 404s as normal boundary errors (#9015) | ||
- feat: adds `defer()` support to data routers (#9002) | ||
- feat: add basename support for data routers (#9026) | ||
- ci: simplify dist/ directory for CJS/ESM only (#9017) | ||
- fix: Fix trailing slash behavior on pathless routing when using a basename (#9045) | ||
## 0.2.0-pre.3 | ||
### Patch Changes | ||
- fix: properly handle `<Form encType="multipart/form-data">` submissions (#8984) | ||
- fix: Make path resolution trailing slash agnostic (#8861) | ||
- fix: don't default to a `REPLACE` navigation on form submissions if the action redirected. The redirect takes care of avoiding the back-button-resubmit scenario, so by using a `PUSH` we allow the back button to go back to the pre-submission form page (#8979) | ||
- fix: export ActionFunctionArgs/LoaderFunctionArgs up through router packages (#8975) | ||
- fix: preserve loader data for loaders that opted out of revalidation (#8973) | ||
[Full Changes](https://github.com/remix-run/react-router/compare/%40remix-run/router%400.2.0-pre.2...%40remix-run/router%400.2.0-pre.3) | ||
## 0.2.0-pre.2 | ||
### Patch Changes | ||
- Capture fetcher errors at contextual route error boundaries (#8945) | ||
## 0.2.0-pre.1 | ||
### Patch Changes | ||
- Fix missing `dist` files | ||
## 0.2.0-pre.0 | ||
### Minor Changes | ||
- Change `formMethod=GET` to be a loading navigation instead of submitting | ||
### Patch Changes | ||
- Make `fallbackElement` optional and change type to `ReactNode` (type changes only) (#8896) | ||
- Properly trigger error boundaries on 404 routes | ||
- Fix `resolveTo` so that it does not mutate the provided pathname (#8839) | ||
- Pass fetcher `actionResult` through to `shouldRevalidate` on fetcher submissions | ||
[rr-docs]: https://reactrouter.com/ | ||
[rr-feature-overview]: https://reactrouter.com/en/v6.4.0/start/overview | ||
[rr-tutorial]: https://reactrouter.com/en/v6.4.0/start/tutorial | ||
[remix-router-readme]: https://github.com/remix-run/react-router/blob/main/packages/router/README.md |
@@ -10,2 +10,5 @@ import type { History, Location, To } from "./history"; | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Return the basename for the router | ||
@@ -15,2 +18,5 @@ */ | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Return the current state of the router | ||
@@ -20,2 +26,5 @@ */ | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Return the routes for this router instance | ||
@@ -25,2 +34,5 @@ */ | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Initialize the router, including adding history listeners and kicking off | ||
@@ -32,2 +44,5 @@ * initial data fetches. Returns a function to cleanup listeners and abort | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Subscribe to router.state updates | ||
@@ -39,2 +54,5 @@ * | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Enable scroll restoration behavior in the router | ||
@@ -49,2 +67,5 @@ * | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Navigate forward/backward in the history stack | ||
@@ -61,2 +82,5 @@ * @param to Delta to move in the history stack | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Trigger a fetcher load/submission | ||
@@ -71,2 +95,5 @@ * | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Trigger a revalidation of all current route loaders and fetcher loads | ||
@@ -76,2 +103,5 @@ */ | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Utility function to create an href for the given location | ||
@@ -82,2 +112,5 @@ * @param location | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Get/create a fetcher for the given key | ||
@@ -88,2 +121,5 @@ * @param key | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Delete the fetcher for a given key | ||
@@ -94,2 +130,5 @@ * @param key | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Cleanup listeners and abort any in-progress loads | ||
@@ -99,9 +138,13 @@ */ | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Internal fetch AbortControllers accessed by unit tests | ||
* @private | ||
*/ | ||
_internalFetchControllers: Map<string, AbortController>; | ||
/** | ||
* @internal | ||
* PRIVATE - DO NOT USE | ||
* | ||
* Internal pending DeferredData instances accessed by unit tests | ||
* @private | ||
*/ | ||
@@ -108,0 +151,0 @@ _internalActiveDeferreds: Map<string, DeferredData>; |
{ | ||
"name": "@remix-run/router", | ||
"version": "0.2.0-pre.10", | ||
"version": "1.0.0", | ||
"description": "Nested/Data-driven/Framework-agnostic Routing", | ||
@@ -26,2 +26,5 @@ "keywords": [ | ||
], | ||
"engines": { | ||
"node": ">=14" | ||
}, | ||
"publishConfig": { | ||
@@ -28,0 +31,0 @@ "access": "public" |
@@ -1,10 +0,11 @@ | ||
# Router | ||
# Remix Router | ||
The `@remix-run/router` package is the heart of [React Router](https://github.com/remix-run/react-router) and provides all the core functionality for routing, data loading, data mutations, and navigation. | ||
The `@remix-run/router` package is a framework-agnostic routing package (sometimes referred to as a browser-emulator) that serves as the heart of [React Router][react-router] and [Remix][remix] and provides all the core functionality for routing coupled with data loading and data mutations. It comes with built-in handling of errors, race-conditions, interruptions, cancellations, lazy-loading data, and much, much more. | ||
If you're using React Router, you should never `import` anything directly from | ||
the `@remix-run/router` or `react-router` packages, but you should have everything | ||
you need in either `react-router-dom` or `react-router-native`. Both of those | ||
packages re-export everything from `@remix-run/router` and `react-router`. | ||
If you're using React Router, you should never `import` anything directly from the `@remix-run/router` or `react-router` packages, but you should have everything you need in either `react-router-dom` or `react-router-native`. Both of those packages re-export everything from `@remix-run/router` and `react-router`. | ||
> **Warning** | ||
> | ||
> This router is a low-level package intended to be consumed by UI layer routing libraries. You should very likely not be using this package directly unless you are authoring a routing library such as [`react-router-dom`][react-router-repo] or one of it's other [UI ports][remix-routers-repo]. | ||
## API | ||
@@ -18,8 +19,6 @@ | ||
let router = createRouter({ | ||
// Routes array using react-router RouteObject's | ||
routes, | ||
// Routes array | ||
routes: , | ||
// History instance | ||
history, | ||
// Optional hydration data for SSR apps | ||
hydrationData?: HydrationState; | ||
}).initialize() | ||
@@ -32,2 +31,4 @@ ``` | ||
interface RouterState { | ||
// False during the initial data load, true once we have our initial data | ||
initialized: boolean; | ||
// The `history` action of the most recently completed navigation | ||
@@ -40,14 +41,6 @@ historyAction: Action; | ||
matches: DataRouteMatch[]; | ||
// False during the initial data load, true once we have our initial data | ||
initialized: boolean; | ||
// The state of the current navigation | ||
navigation: Navigation; | ||
// The state of an in-progress router.revalidate() calls | ||
// The state of any in-progress router.revalidate() calls | ||
revalidation: RevalidationState; | ||
// Scroll position to restore to for the active Location, false if we | ||
// should not restore,m or null if we don't have a saved position | ||
// Note: must be enabled via router.enableScrollRestoration() | ||
restoreScrollPosition: number | false | null; | ||
// Proxied `preventScrollReset` value passed to router.navigate() (default false) | ||
preventScrollReset: boolean; | ||
// Data from the loaders for the current matches | ||
@@ -61,2 +54,8 @@ loaderData: RouteData; | ||
fetchers: Map<string, Fetcher>; | ||
// Scroll position to restore to for the active Location, false if we | ||
// should not restore, or null if we don't have a saved position | ||
// Note: must be enabled via router.enableScrollRestoration() | ||
restoreScrollPosition: number | false | null; | ||
// Proxied `preventScrollReset` value passed to router.navigate() | ||
preventScrollReset: boolean; | ||
} | ||
@@ -105,4 +104,9 @@ ``` | ||
## Revalidation | ||
### Revalidation | ||
By default, active loaders will revalidate after any navigation or fetcher mutation. If you need to kick off a revalidation for other use-cases, you can use `router.revalidate()` to re-execute all active loaders. | ||
[react-router]: https://reactrouter.com | ||
[remix]: https://remix.run | ||
[react-router-repo]: https://github.com/remix-run/react-router | ||
[remix-routers-repo]: https://github.com/brophdawg11/remix-routers |
11
utils.ts
@@ -488,6 +488,13 @@ import type { Location, Path, To } from "./history"; | ||
}) | ||
.replace(/\/*\*$/, (_) => { | ||
.replace(/(\/?)\*/, (_, prefix, __, str) => { | ||
const star = "*" as PathParam<Path>; | ||
return params[star] == null ? "" : params[star].replace(/^\/*/, "/"); | ||
if (params[star] == null) { | ||
// If no splat was provided, trim the trailing slash _unless_ it's | ||
// the entire path | ||
return str === "/*" ? "/" : ""; | ||
} | ||
// Apply the splat | ||
return `${prefix}${params[star]}`; | ||
}); | ||
@@ -494,0 +501,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10298
1
108
848575