From a98826b8ae68ce71e5c6e5de0920f16d3a155609 Mon Sep 17 00:00:00 2001 From: Jacob Ebey Date: Tue, 26 Mar 2024 21:35:30 -0700 Subject: [PATCH] feat!: remove @remix-run/router package --- .changeset/remove-router-pkg.md | 8 + package.json | 11 +- .../react-router-dom-v5-compat/package.json | 1 - .../concurrent-mode-navigations-test.tsx | 2 +- .../__tests__/data-browser-router-test.tsx | 4 +- .../__tests__/data-static-router-test.tsx | 2 +- .../__tests__/partial-hydration-test.tsx | 2 +- packages/react-router-dom/dom.ts | 4 +- packages/react-router-dom/index.tsx | 26 +- packages/react-router-dom/package.json | 1 - packages/react-router-dom/server.tsx | 6 +- packages/react-router-native/index.tsx | 21 +- .../__tests__/data-memory-router-test.tsx | 6 +- .../descendant-routes-splat-matching-test.tsx | 2 +- .../__tests__/utils/MemoryNavigate.tsx | 5 +- packages/react-router/index.ts | 73 +- packages/react-router/lib/components.tsx | 5 +- packages/react-router/lib/context.ts | 2 +- packages/react-router/lib/hooks.tsx | 4 +- packages/react-router/package.json | 3 - .../router/__tests__/.eslintrc | 0 .../EncodedReservedCharacters.ts | 0 .../router/__tests__/TestSequences/GoBack.ts | 0 .../__tests__/TestSequences/GoForward.ts | 0 .../InitialLocationDefaultKey.ts | 0 .../TestSequences/InitialLocationHasKey.ts | 0 .../router/__tests__/TestSequences/Listen.ts | 0 .../__tests__/TestSequences/ListenPopOnly.ts | 0 .../TestSequences/PushMissingPathname.ts | 0 .../TestSequences/PushNewLocation.ts | 0 .../TestSequences/PushRelativePathname.ts | 0 .../PushRelativePathnameWarning.ts | 0 .../__tests__/TestSequences/PushSamePath.ts | 0 .../__tests__/TestSequences/PushState.ts | 0 .../TestSequences/PushStateInvalid.ts | 0 .../TestSequences/ReplaceNewLocation.ts | 0 .../TestSequences/ReplaceSamePath.ts | 0 .../__tests__/TestSequences/ReplaceState.ts | 0 .../router/__tests__/browser-test.ts | 4 +- .../router/__tests__/create-path-test.ts | 2 +- .../router/__tests__/data-strategy-test.ts | 0 .../router/__tests__/defer-test.ts | 0 .../router/__tests__/fetchers-test.ts | 0 .../router/__tests__/flush-sync-test.ts | 0 .../router/__tests__/hash-base-test.ts | 4 +- .../router/__tests__/hash-test.ts | 4 +- .../router/__tests__/interruptions-test.ts | 0 .../router/__tests__/lazy-test.ts | 0 .../router/__tests__/memory-test.ts | 4 +- .../__tests__/navigation-blocking-test.ts | 0 .../router/__tests__/navigation-test.ts | 12 +- .../router/__tests__/path-resolution-test.ts | 0 .../router/__tests__/redirects-test.ts | 0 .../router/__tests__/resolveTo-test.tsx | 2 +- .../router/__tests__/revalidate-test.ts | 0 .../router/__tests__/route-fallback-test.ts | 0 .../router/__tests__/router-memory-test.ts | 0 .../router/__tests__/router-test.ts | 0 .../__tests__/scroll-restoration-test.ts | 0 .../router/__tests__/setup.ts | 0 .../__tests__/should-revalidate-test.ts | 0 .../router/__tests__/ssr-test.ts | 0 .../router/__tests__/submission-test.ts | 0 .../router/__tests__/utils/custom-matchers.ts | 0 .../__tests__/utils/data-router-setup.ts | 1 - .../router/__tests__/utils/urlDataStrategy.ts | 2 +- .../router/__tests__/utils/utils.ts | 0 .../router/__tests__/view-transition-test.ts | 0 packages/{ => react-router}/router/history.ts | 0 packages/{ => react-router}/router/index.ts | 0 packages/{ => react-router}/router/router.ts | 4 +- packages/{ => react-router}/router/utils.ts | 2 +- packages/router/.eslintrc | 10 - packages/router/CHANGELOG.md | 716 ------------------ packages/router/README.md | 135 ---- packages/router/jest.config.js | 5 - packages/router/package.json | 33 - packages/router/rollup.config.js | 82 -- packages/router/tsconfig.json | 20 - pnpm-lock.yaml | 12 - scripts/publish.js | 6 - scripts/version.js | 26 - 82 files changed, 158 insertions(+), 1116 deletions(-) create mode 100644 .changeset/remove-router-pkg.md rename packages/{ => react-router}/router/__tests__/.eslintrc (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/EncodedReservedCharacters.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/GoBack.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/GoForward.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/InitialLocationDefaultKey.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/InitialLocationHasKey.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/Listen.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/ListenPopOnly.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushMissingPathname.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushNewLocation.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushRelativePathname.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushRelativePathnameWarning.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushSamePath.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushState.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/PushStateInvalid.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/ReplaceNewLocation.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/ReplaceSamePath.ts (100%) rename packages/{ => react-router}/router/__tests__/TestSequences/ReplaceState.ts (100%) rename packages/{ => react-router}/router/__tests__/browser-test.ts (97%) rename packages/{ => react-router}/router/__tests__/create-path-test.ts (97%) rename packages/{ => react-router}/router/__tests__/data-strategy-test.ts (100%) rename packages/{ => react-router}/router/__tests__/defer-test.ts (100%) rename packages/{ => react-router}/router/__tests__/fetchers-test.ts (100%) rename packages/{ => react-router}/router/__tests__/flush-sync-test.ts (100%) rename packages/{ => react-router}/router/__tests__/hash-base-test.ts (91%) rename packages/{ => react-router}/router/__tests__/hash-test.ts (97%) rename packages/{ => react-router}/router/__tests__/interruptions-test.ts (100%) rename packages/{ => react-router}/router/__tests__/lazy-test.ts (100%) rename packages/{ => react-router}/router/__tests__/memory-test.ts (97%) rename packages/{ => react-router}/router/__tests__/navigation-blocking-test.ts (100%) rename packages/{ => react-router}/router/__tests__/navigation-test.ts (99%) rename packages/{ => react-router}/router/__tests__/path-resolution-test.ts (100%) rename packages/{ => react-router}/router/__tests__/redirects-test.ts (100%) rename packages/{ => react-router}/router/__tests__/resolveTo-test.tsx (93%) rename packages/{ => react-router}/router/__tests__/revalidate-test.ts (100%) rename packages/{ => react-router}/router/__tests__/route-fallback-test.ts (100%) rename packages/{ => react-router}/router/__tests__/router-memory-test.ts (100%) rename packages/{ => react-router}/router/__tests__/router-test.ts (100%) rename packages/{ => react-router}/router/__tests__/scroll-restoration-test.ts (100%) rename packages/{ => react-router}/router/__tests__/setup.ts (100%) rename packages/{ => react-router}/router/__tests__/should-revalidate-test.ts (100%) rename packages/{ => react-router}/router/__tests__/ssr-test.ts (100%) rename packages/{ => react-router}/router/__tests__/submission-test.ts (100%) rename packages/{ => react-router}/router/__tests__/utils/custom-matchers.ts (100%) rename packages/{ => react-router}/router/__tests__/utils/data-router-setup.ts (99%) rename packages/{ => react-router}/router/__tests__/utils/urlDataStrategy.ts (96%) rename packages/{ => react-router}/router/__tests__/utils/utils.ts (100%) rename packages/{ => react-router}/router/__tests__/view-transition-test.ts (100%) rename packages/{ => react-router}/router/history.ts (100%) rename packages/{ => react-router}/router/index.ts (100%) rename packages/{ => react-router}/router/router.ts (99%) rename packages/{ => react-router}/router/utils.ts (99%) delete mode 100644 packages/router/.eslintrc delete mode 100644 packages/router/CHANGELOG.md delete mode 100644 packages/router/README.md delete mode 100644 packages/router/jest.config.js delete mode 100644 packages/router/package.json delete mode 100644 packages/router/rollup.config.js delete mode 100644 packages/router/tsconfig.json diff --git a/.changeset/remove-router-pkg.md b/.changeset/remove-router-pkg.md new file mode 100644 index 0000000000..8a6491e996 --- /dev/null +++ b/.changeset/remove-router-pkg.md @@ -0,0 +1,8 @@ +--- +"react-router-dom-v5-compat": major +"react-router-native": major +"react-router-dom": major +"react-router": major +--- + +remove @remix-run/router package diff --git a/package.json b/package.json index a23f3681f8..1ff587dece 100644 --- a/package.json +++ b/package.json @@ -109,20 +109,17 @@ "node": ">=14.0.0" }, "filesize": { - "packages/router/dist/router.umd.min.js": { - "none": "52.4 kB" - }, "packages/react-router/dist/react-router.production.min.js": { - "none": "14.8 kB" + "none": "61.2 kB" }, "packages/react-router/dist/umd/react-router.production.min.js": { - "none": "17.2 kB" + "none": "63.2 kB" }, "packages/react-router-dom/dist/react-router-dom.production.min.js": { - "none": "17.1 kB" + "none": "17.4 kB" }, "packages/react-router-dom/dist/umd/react-router-dom.production.min.js": { - "none": "23.5 kB" + "none": "24.9 kB" } }, "pnpm": { diff --git a/packages/react-router-dom-v5-compat/package.json b/packages/react-router-dom-v5-compat/package.json index 8d6224f0c7..070d35acbc 100644 --- a/packages/react-router-dom-v5-compat/package.json +++ b/packages/react-router-dom-v5-compat/package.json @@ -23,7 +23,6 @@ "module": "./dist/index.js", "types": "./dist/index.d.ts", "dependencies": { - "@remix-run/router": "workspace:*", "history": "^5.3.0", "react-router": "workspace:*" }, diff --git a/packages/react-router-dom/__tests__/concurrent-mode-navigations-test.tsx b/packages/react-router-dom/__tests__/concurrent-mode-navigations-test.tsx index a07c3bcf02..ada334e079 100644 --- a/packages/react-router-dom/__tests__/concurrent-mode-navigations-test.tsx +++ b/packages/react-router-dom/__tests__/concurrent-mode-navigations-test.tsx @@ -18,7 +18,7 @@ import { waitFor, } from "@testing-library/react"; import { JSDOM } from "jsdom"; -import { createDeferred } from "../../router/__tests__/utils/utils"; +import { createDeferred } from "react-router/router/__tests__/utils/utils"; import getHtml from "react-router/__tests__/utils/getHtml"; describe("Handles concurrent mode features during navigations", () => { diff --git a/packages/react-router-dom/__tests__/data-browser-router-test.tsx b/packages/react-router-dom/__tests__/data-browser-router-test.tsx index 0ae3c3824f..9fbf1d3ac1 100644 --- a/packages/react-router-dom/__tests__/data-browser-router-test.tsx +++ b/packages/react-router-dom/__tests__/data-browser-router-test.tsx @@ -1,4 +1,4 @@ -import type { ErrorResponse, Fetcher } from "@remix-run/router"; +import type { ErrorResponse, Fetcher } from "react-router"; import "@testing-library/jest-dom"; import { act, @@ -37,7 +37,7 @@ import { } from "react-router-dom"; import getHtml from "../../react-router/__tests__/utils/getHtml"; -import { createDeferred } from "../../router/__tests__/utils/utils"; +import { createDeferred } from "../../react-router/router/__tests__/utils/utils"; testDomRouter("", createBrowserRouter, (url) => getWindowImpl(url, false) diff --git a/packages/react-router-dom/__tests__/data-static-router-test.tsx b/packages/react-router-dom/__tests__/data-static-router-test.tsx index 5a4050d48e..2ebed0c56a 100644 --- a/packages/react-router-dom/__tests__/data-static-router-test.tsx +++ b/packages/react-router-dom/__tests__/data-static-router-test.tsx @@ -4,11 +4,11 @@ import * as React from "react"; import * as ReactDOMServer from "react-dom/server"; -import { json } from "@remix-run/router"; import { Form, Link, Outlet, + json, useLoaderData, useLocation, useMatches, diff --git a/packages/react-router-dom/__tests__/partial-hydration-test.tsx b/packages/react-router-dom/__tests__/partial-hydration-test.tsx index dac2f3d5d9..75e0d787d5 100644 --- a/packages/react-router-dom/__tests__/partial-hydration-test.tsx +++ b/packages/react-router-dom/__tests__/partial-hydration-test.tsx @@ -14,7 +14,7 @@ import { } from "react-router-dom"; import getHtml from "../../react-router/__tests__/utils/getHtml"; -import { createDeferred, tick } from "../../router/__tests__/utils/utils"; +import { createDeferred, tick } from "../../react-router/router/__tests__/utils/utils"; let didAssertMissingHydrateFallback = false; diff --git a/packages/react-router-dom/dom.ts b/packages/react-router-dom/dom.ts index 960e0b5036..2fdcb87889 100644 --- a/packages/react-router-dom/dom.ts +++ b/packages/react-router-dom/dom.ts @@ -2,8 +2,8 @@ import type { FormEncType, HTMLFormMethod, RelativeRoutingType, -} from "@remix-run/router"; -import { stripBasename, UNSAFE_warning as warning } from "@remix-run/router"; +} from "react-router"; +import { stripBasename, UNSAFE_warning as warning } from "react-router"; export const defaultMethod: HTMLFormMethod = "get"; const defaultEncType: FormEncType = "application/x-www-form-urlencoded"; diff --git a/packages/react-router-dom/index.tsx b/packages/react-router-dom/index.tsx index 1d4675396e..61d5651751 100644 --- a/packages/react-router-dom/index.tsx +++ b/packages/react-router-dom/index.tsx @@ -48,12 +48,12 @@ import type { History, HTMLFormMethod, HydrationState, - Router as RemixRouter, + RemixRouter, V7_FormMethod, RouterState, RouterSubscriber, BlockerFunction, -} from "@remix-run/router"; +} from "react-router"; import { createRouter, createBrowserHistory, @@ -65,7 +65,7 @@ import { UNSAFE_warning as warning, matchPath, IDLE_FETCHER, -} from "@remix-run/router"; +} from "react-router"; import type { SubmitOptions, @@ -93,11 +93,12 @@ export type { FormMethod, GetScrollRestorationKeyFunction, ParamKeyValuePair, + RouterProviderProps, SubmitOptions, URLSearchParamsInit, V7_FormMethod, }; -export { createSearchParams, ErrorResponseImpl as UNSAFE_ErrorResponseImpl }; +export { createSearchParams }; // Note: Keep in sync with react-router exports! export type { @@ -142,7 +143,6 @@ export type { RouteObject, RouteProps, RouterProps, - RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, @@ -152,6 +152,7 @@ export type { unstable_HandlerResult, } from "react-router"; export { + Action, AbortedDeferredError, Await, MemoryRouter, @@ -161,13 +162,22 @@ export { Route, Router, Routes, + createBrowserHistory, + createHashHistory, + createMemoryHistory, createMemoryRouter, createPath, + createRouter, createRoutesFromChildren, createRoutesFromElements, + createStaticHandler, defer, + IDLE_BLOCKER, + IDLE_FETCHER, + IDLE_NAVIGATION, isRouteErrorResponse, generatePath, + joinPaths, json, matchPath, matchRoutes, @@ -176,6 +186,12 @@ export { redirectDocument, renderMatches, resolvePath, + resolveTo, + stripBasename, + UNSAFE_convertRoutesToDataRoutes, + UNSAFE_ErrorResponseImpl, + UNSAFE_invariant, + UNSAFE_warning, useActionData, useAsyncError, useAsyncValue, diff --git a/packages/react-router-dom/package.json b/packages/react-router-dom/package.json index 8fdba2481d..188b35c517 100644 --- a/packages/react-router-dom/package.json +++ b/packages/react-router-dom/package.json @@ -23,7 +23,6 @@ "module": "./dist/index.js", "types": "./dist/index.d.ts", "dependencies": { - "@remix-run/router": "workspace:*", "react-router": "workspace:*" }, "devDependencies": { diff --git a/packages/react-router-dom/server.tsx b/packages/react-router-dom/server.tsx index 3195c3d271..f466a48c73 100644 --- a/packages/react-router-dom/server.tsx +++ b/packages/react-router-dom/server.tsx @@ -2,13 +2,13 @@ import * as React from "react"; import type { Path, RevalidationState, - Router as RemixRouter, + RemixRouter, StaticHandlerContext, CreateStaticHandlerOptions as RouterCreateStaticHandlerOptions, UNSAFE_RouteManifest as RouteManifest, RouterState, FutureConfig as RouterFutureConfig, -} from "@remix-run/router"; +} from "react-router"; import { IDLE_BLOCKER, IDLE_FETCHER, @@ -18,7 +18,7 @@ import { isRouteErrorResponse, createStaticHandler as routerCreateStaticHandler, UNSAFE_convertRoutesToDataRoutes as convertRoutesToDataRoutes, -} from "@remix-run/router"; +} from "react-router"; import { UNSAFE_mapRouteProperties as mapRouteProperties, UNSAFE_useRoutesImpl as useRoutesImpl, diff --git a/packages/react-router-native/index.tsx b/packages/react-router-native/index.tsx index 562a298540..2261e6ccf2 100644 --- a/packages/react-router-native/index.tsx +++ b/packages/react-router-native/index.tsx @@ -27,9 +27,6 @@ export type { BlockerFunction, DataRouteMatch, DataRouteObject, - unstable_DataStrategyFunction, - unstable_DataStrategyFunctionArgs, - unstable_DataStrategyMatch, ErrorResponse, Fetcher, FutureConfig, @@ -74,6 +71,7 @@ export type { unstable_HandlerResult, } from "react-router"; export { + Action, AbortedDeferredError, Await, MemoryRouter, @@ -82,15 +80,23 @@ export { Outlet, Route, Router, - RouterProvider, Routes, + createBrowserHistory, + createHashHistory, + createMemoryHistory, createMemoryRouter, createPath, + createRouter, createRoutesFromChildren, createRoutesFromElements, + createStaticHandler, defer, + IDLE_BLOCKER, + IDLE_FETCHER, + IDLE_NAVIGATION, isRouteErrorResponse, generatePath, + joinPaths, json, matchPath, matchRoutes, @@ -99,6 +105,13 @@ export { redirectDocument, renderMatches, resolvePath, + resolveTo, + RouterProvider, + stripBasename, + UNSAFE_convertRoutesToDataRoutes, + UNSAFE_ErrorResponseImpl, + UNSAFE_invariant, + UNSAFE_warning, useActionData, useAsyncError, useAsyncValue, diff --git a/packages/react-router/__tests__/data-memory-router-test.tsx b/packages/react-router/__tests__/data-memory-router-test.tsx index 4a4826dd2c..0e35beed30 100644 --- a/packages/react-router/__tests__/data-memory-router-test.tsx +++ b/packages/react-router/__tests__/data-memory-router-test.tsx @@ -1,4 +1,3 @@ -import type { ErrorResponse } from "@remix-run/router"; import "@testing-library/jest-dom"; import { fireEvent, @@ -29,9 +28,10 @@ import { useRouteError, useRouteLoaderData, } from "react-router"; +import type { ErrorResponse } from "react-router"; -import urlDataStrategy from "../../router/__tests__/utils/urlDataStrategy"; -import { createDeferred } from "../../router/__tests__/utils/utils"; +import urlDataStrategy from "../router/__tests__/utils/urlDataStrategy"; +import { createDeferred } from "../router/__tests__/utils/utils"; import MemoryNavigate from "./utils/MemoryNavigate"; import getHtml from "./utils/getHtml"; diff --git a/packages/react-router/__tests__/descendant-routes-splat-matching-test.tsx b/packages/react-router/__tests__/descendant-routes-splat-matching-test.tsx index a5fce5a781..ef63eb1437 100644 --- a/packages/react-router/__tests__/descendant-routes-splat-matching-test.tsx +++ b/packages/react-router/__tests__/descendant-routes-splat-matching-test.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import * as TestRenderer from "react-test-renderer"; import { MemoryRouter, Outlet, Routes, Route, useParams } from "react-router"; -import type { InitialEntry } from "@remix-run/router"; +import type { InitialEntry } from "react-router"; describe("Descendant splat matching", () => { describe("when the parent route path ends with /*", () => { diff --git a/packages/react-router/__tests__/utils/MemoryNavigate.tsx b/packages/react-router/__tests__/utils/MemoryNavigate.tsx index 9f418cd619..b230f2be64 100644 --- a/packages/react-router/__tests__/utils/MemoryNavigate.tsx +++ b/packages/react-router/__tests__/utils/MemoryNavigate.tsx @@ -1,7 +1,6 @@ -import type { FormMethod } from "@remix-run/router"; -import { joinPaths } from "@remix-run/router"; import * as React from "react"; -import { UNSAFE_DataRouterContext } from "react-router"; +import { joinPaths, UNSAFE_DataRouterContext } from "react-router"; +import type { FormMethod } from "react-router"; export default function MemoryNavigate({ to, diff --git a/packages/react-router/index.ts b/packages/react-router/index.ts index b6d85af431..c1e1d66abe 100644 --- a/packages/react-router/index.ts +++ b/packages/react-router/index.ts @@ -2,13 +2,25 @@ import * as React from "react"; import type { ActionFunction, ActionFunctionArgs, + AgnosticRouteObject, Blocker, BlockerFunction, + BrowserHistory, + BrowserHistoryOptions, + CreateStaticHandlerOptions, unstable_DataStrategyFunction, unstable_DataStrategyFunctionArgs, unstable_DataStrategyMatch, ErrorResponse, Fetcher, + FormEncType, + FormMethod, + V7_FormMethod, + GetScrollRestorationKeyFunction, + History, + HashHistory, + HashHistoryOptions, + HTMLFormMethod, HydrationState, InitialEntry, JsonFunction, @@ -16,6 +28,8 @@ import type { LoaderFunction, LoaderFunctionArgs, Location, + MemoryHistory, + MemoryHistoryOptions, Navigation, ParamParseKey, Params, @@ -25,23 +39,35 @@ import type { PathPattern, RedirectFunction, RelativeRoutingType, + RevalidationState, Router as RemixRouter, + RouterState, + RouterSubscriber, FutureConfig as RouterFutureConfig, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, + StaticHandlerContext, To, UIMatch, + UNSAFE_RouteManifest, unstable_HandlerResult, -} from "@remix-run/router"; +} from "./router"; import { AbortedDeferredError, Action as NavigationType, + createBrowserHistory, + createHashHistory, createMemoryHistory, createPath, createRouter, + createStaticHandler, defer, generatePath, + IDLE_BLOCKER, + IDLE_FETCHER, + IDLE_NAVIGATION, isRouteErrorResponse, + joinPaths, json, matchPath, matchRoutes, @@ -49,8 +75,13 @@ import { redirect, redirectDocument, resolvePath, + resolveTo, + stripBasename, + UNSAFE_convertRoutesToDataRoutes, + UNSAFE_ErrorResponseImpl, + UNSAFE_invariant, UNSAFE_warning as warning, -} from "@remix-run/router"; +} from "./router"; import type { AwaitProps, @@ -132,6 +163,9 @@ export type { ActionFunction, ActionFunctionArgs, AwaitProps, + BrowserHistory, + BrowserHistoryOptions, + CreateStaticHandlerOptions, DataRouteMatch, DataRouteObject, unstable_DataStrategyFunction, @@ -139,8 +173,17 @@ export type { unstable_DataStrategyMatch, ErrorResponse, Fetcher, + FormEncType, + FormMethod, + V7_FormMethod, FutureConfig, + GetScrollRestorationKeyFunction, Hash, + HashHistory, + HashHistoryOptions, + History, + HTMLFormMethod, + HydrationState, IndexRouteObject, IndexRouteProps, JsonFunction, @@ -149,6 +192,8 @@ export type { LoaderFunction, LoaderFunctionArgs, Location, + MemoryHistory, + MemoryHistoryOptions, MemoryRouterProps, NavigateFunction, NavigateOptions, @@ -167,23 +212,30 @@ export type { Pathname, RedirectFunction, RelativeRoutingType, + RemixRouter, + RevalidationState, RouteMatch, RouteObject, RouteProps, + RouterState, + RouterSubscriber, RouterProps, RouterProviderProps, RoutesProps, Search, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, + StaticHandlerContext, To, UIMatch, Blocker, BlockerFunction, + UNSAFE_RouteManifest, unstable_HandlerResult, }; export { AbortedDeferredError, + NavigationType as Action, Await, MemoryRouter, Navigate, @@ -193,12 +245,21 @@ export { Router, RouterProvider, Routes, + createBrowserHistory, + createHashHistory, + createMemoryHistory, createPath, + createRouter, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, + createStaticHandler, defer, generatePath, + IDLE_BLOCKER, + IDLE_FETCHER, + IDLE_NAVIGATION, isRouteErrorResponse, + joinPaths, json, matchPath, matchRoutes, @@ -207,6 +268,11 @@ export { redirectDocument, renderMatches, resolvePath, + resolveTo, + stripBasename, + UNSAFE_convertRoutesToDataRoutes, + UNSAFE_ErrorResponseImpl, + UNSAFE_invariant, useBlocker, useActionData, useAsyncError, @@ -228,6 +294,7 @@ export { useRouteError, useRouteLoaderData, useRoutes, + warning as UNSAFE_warning, }; function mapRouteProperties(route: RouteObject) { @@ -289,7 +356,7 @@ function mapRouteProperties(route: RouteObject) { } export function createMemoryRouter( - routes: RouteObject[], + routes: AgnosticRouteObject[], opts?: { basename?: string; future?: Partial>; diff --git a/packages/react-router/lib/components.tsx b/packages/react-router/lib/components.tsx index 918bc34d39..20be08e413 100644 --- a/packages/react-router/lib/components.tsx +++ b/packages/react-router/lib/components.tsx @@ -9,7 +9,7 @@ import type { RouterSubscriber, To, TrackedPromise, -} from "@remix-run/router"; +} from "../router"; import { AbortedDeferredError, Action as NavigationType, @@ -20,7 +20,7 @@ import { resolveTo, stripBasename, UNSAFE_warning as warning, -} from "@remix-run/router"; +} from "../router"; import * as React from "react"; import type { @@ -51,6 +51,7 @@ import { } from "./hooks"; export interface FutureConfig { + v7_partialHydration: boolean; v7_relativeSplatPath: boolean; v7_startTransition: boolean; } diff --git a/packages/react-router/lib/context.ts b/packages/react-router/lib/context.ts index a98168217a..f2491260b2 100644 --- a/packages/react-router/lib/context.ts +++ b/packages/react-router/lib/context.ts @@ -12,7 +12,7 @@ import type { StaticHandlerContext, To, TrackedPromise, -} from "@remix-run/router"; +} from "../router"; // Create react-specific types from the agnostic types in @remix-run/router to // export from react-router diff --git a/packages/react-router/lib/hooks.tsx b/packages/react-router/lib/hooks.tsx index 37697ee647..7c3b331708 100644 --- a/packages/react-router/lib/hooks.tsx +++ b/packages/react-router/lib/hooks.tsx @@ -13,7 +13,7 @@ import type { RevalidationState, To, UIMatch, -} from "@remix-run/router"; +} from "../router"; import { IDLE_BLOCKER, Action as NavigationType, @@ -28,7 +28,7 @@ import { resolveTo, stripBasename, UNSAFE_warning as warning, -} from "@remix-run/router"; +} from "../router"; import type { DataRouteMatch, diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 90fb508973..31a5ef2127 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -22,9 +22,6 @@ "unpkg": "./dist/umd/react-router.production.min.js", "module": "./dist/index.js", "types": "./dist/index.d.ts", - "dependencies": { - "@remix-run/router": "workspace:*" - }, "devDependencies": { "react": "^18.2.0", "react-router-dom": "workspace:*" diff --git a/packages/router/__tests__/.eslintrc b/packages/react-router/router/__tests__/.eslintrc similarity index 100% rename from packages/router/__tests__/.eslintrc rename to packages/react-router/router/__tests__/.eslintrc diff --git a/packages/router/__tests__/TestSequences/EncodedReservedCharacters.ts b/packages/react-router/router/__tests__/TestSequences/EncodedReservedCharacters.ts similarity index 100% rename from packages/router/__tests__/TestSequences/EncodedReservedCharacters.ts rename to packages/react-router/router/__tests__/TestSequences/EncodedReservedCharacters.ts diff --git a/packages/router/__tests__/TestSequences/GoBack.ts b/packages/react-router/router/__tests__/TestSequences/GoBack.ts similarity index 100% rename from packages/router/__tests__/TestSequences/GoBack.ts rename to packages/react-router/router/__tests__/TestSequences/GoBack.ts diff --git a/packages/router/__tests__/TestSequences/GoForward.ts b/packages/react-router/router/__tests__/TestSequences/GoForward.ts similarity index 100% rename from packages/router/__tests__/TestSequences/GoForward.ts rename to packages/react-router/router/__tests__/TestSequences/GoForward.ts diff --git a/packages/router/__tests__/TestSequences/InitialLocationDefaultKey.ts b/packages/react-router/router/__tests__/TestSequences/InitialLocationDefaultKey.ts similarity index 100% rename from packages/router/__tests__/TestSequences/InitialLocationDefaultKey.ts rename to packages/react-router/router/__tests__/TestSequences/InitialLocationDefaultKey.ts diff --git a/packages/router/__tests__/TestSequences/InitialLocationHasKey.ts b/packages/react-router/router/__tests__/TestSequences/InitialLocationHasKey.ts similarity index 100% rename from packages/router/__tests__/TestSequences/InitialLocationHasKey.ts rename to packages/react-router/router/__tests__/TestSequences/InitialLocationHasKey.ts diff --git a/packages/router/__tests__/TestSequences/Listen.ts b/packages/react-router/router/__tests__/TestSequences/Listen.ts similarity index 100% rename from packages/router/__tests__/TestSequences/Listen.ts rename to packages/react-router/router/__tests__/TestSequences/Listen.ts diff --git a/packages/router/__tests__/TestSequences/ListenPopOnly.ts b/packages/react-router/router/__tests__/TestSequences/ListenPopOnly.ts similarity index 100% rename from packages/router/__tests__/TestSequences/ListenPopOnly.ts rename to packages/react-router/router/__tests__/TestSequences/ListenPopOnly.ts diff --git a/packages/router/__tests__/TestSequences/PushMissingPathname.ts b/packages/react-router/router/__tests__/TestSequences/PushMissingPathname.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushMissingPathname.ts rename to packages/react-router/router/__tests__/TestSequences/PushMissingPathname.ts diff --git a/packages/router/__tests__/TestSequences/PushNewLocation.ts b/packages/react-router/router/__tests__/TestSequences/PushNewLocation.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushNewLocation.ts rename to packages/react-router/router/__tests__/TestSequences/PushNewLocation.ts diff --git a/packages/router/__tests__/TestSequences/PushRelativePathname.ts b/packages/react-router/router/__tests__/TestSequences/PushRelativePathname.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushRelativePathname.ts rename to packages/react-router/router/__tests__/TestSequences/PushRelativePathname.ts diff --git a/packages/router/__tests__/TestSequences/PushRelativePathnameWarning.ts b/packages/react-router/router/__tests__/TestSequences/PushRelativePathnameWarning.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushRelativePathnameWarning.ts rename to packages/react-router/router/__tests__/TestSequences/PushRelativePathnameWarning.ts diff --git a/packages/router/__tests__/TestSequences/PushSamePath.ts b/packages/react-router/router/__tests__/TestSequences/PushSamePath.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushSamePath.ts rename to packages/react-router/router/__tests__/TestSequences/PushSamePath.ts diff --git a/packages/router/__tests__/TestSequences/PushState.ts b/packages/react-router/router/__tests__/TestSequences/PushState.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushState.ts rename to packages/react-router/router/__tests__/TestSequences/PushState.ts diff --git a/packages/router/__tests__/TestSequences/PushStateInvalid.ts b/packages/react-router/router/__tests__/TestSequences/PushStateInvalid.ts similarity index 100% rename from packages/router/__tests__/TestSequences/PushStateInvalid.ts rename to packages/react-router/router/__tests__/TestSequences/PushStateInvalid.ts diff --git a/packages/router/__tests__/TestSequences/ReplaceNewLocation.ts b/packages/react-router/router/__tests__/TestSequences/ReplaceNewLocation.ts similarity index 100% rename from packages/router/__tests__/TestSequences/ReplaceNewLocation.ts rename to packages/react-router/router/__tests__/TestSequences/ReplaceNewLocation.ts diff --git a/packages/router/__tests__/TestSequences/ReplaceSamePath.ts b/packages/react-router/router/__tests__/TestSequences/ReplaceSamePath.ts similarity index 100% rename from packages/router/__tests__/TestSequences/ReplaceSamePath.ts rename to packages/react-router/router/__tests__/TestSequences/ReplaceSamePath.ts diff --git a/packages/router/__tests__/TestSequences/ReplaceState.ts b/packages/react-router/router/__tests__/TestSequences/ReplaceState.ts similarity index 100% rename from packages/router/__tests__/TestSequences/ReplaceState.ts rename to packages/react-router/router/__tests__/TestSequences/ReplaceState.ts diff --git a/packages/router/__tests__/browser-test.ts b/packages/react-router/router/__tests__/browser-test.ts similarity index 97% rename from packages/router/__tests__/browser-test.ts rename to packages/react-router/router/__tests__/browser-test.ts index 64b736f4d9..4961c2f8e5 100644 --- a/packages/router/__tests__/browser-test.ts +++ b/packages/react-router/router/__tests__/browser-test.ts @@ -2,8 +2,8 @@ import { JSDOM } from "jsdom"; -import type { BrowserHistory } from "@remix-run/router"; -import { createBrowserHistory } from "@remix-run/router"; +import type { BrowserHistory } from "react-router"; +import { createBrowserHistory } from "react-router"; import InitialLocationDefaultKey from "./TestSequences/InitialLocationDefaultKey"; import Listen from "./TestSequences/Listen"; diff --git a/packages/router/__tests__/create-path-test.ts b/packages/react-router/router/__tests__/create-path-test.ts similarity index 97% rename from packages/router/__tests__/create-path-test.ts rename to packages/react-router/router/__tests__/create-path-test.ts index 424e5fa47e..c6e9648427 100644 --- a/packages/router/__tests__/create-path-test.ts +++ b/packages/react-router/router/__tests__/create-path-test.ts @@ -1,4 +1,4 @@ -import { createPath } from "@remix-run/router"; +import { createPath } from "react-router"; describe("createPath", () => { describe("given only a pathname", () => { diff --git a/packages/router/__tests__/data-strategy-test.ts b/packages/react-router/router/__tests__/data-strategy-test.ts similarity index 100% rename from packages/router/__tests__/data-strategy-test.ts rename to packages/react-router/router/__tests__/data-strategy-test.ts diff --git a/packages/router/__tests__/defer-test.ts b/packages/react-router/router/__tests__/defer-test.ts similarity index 100% rename from packages/router/__tests__/defer-test.ts rename to packages/react-router/router/__tests__/defer-test.ts diff --git a/packages/router/__tests__/fetchers-test.ts b/packages/react-router/router/__tests__/fetchers-test.ts similarity index 100% rename from packages/router/__tests__/fetchers-test.ts rename to packages/react-router/router/__tests__/fetchers-test.ts diff --git a/packages/router/__tests__/flush-sync-test.ts b/packages/react-router/router/__tests__/flush-sync-test.ts similarity index 100% rename from packages/router/__tests__/flush-sync-test.ts rename to packages/react-router/router/__tests__/flush-sync-test.ts diff --git a/packages/router/__tests__/hash-base-test.ts b/packages/react-router/router/__tests__/hash-base-test.ts similarity index 91% rename from packages/router/__tests__/hash-base-test.ts rename to packages/react-router/router/__tests__/hash-base-test.ts index 511df27394..94102e0d2b 100644 --- a/packages/router/__tests__/hash-base-test.ts +++ b/packages/react-router/router/__tests__/hash-base-test.ts @@ -1,7 +1,7 @@ import { JSDOM } from "jsdom"; -import type { HashHistory } from "@remix-run/router"; -import { createHashHistory } from "@remix-run/router"; +import type { HashHistory } from "react-router"; +import { createHashHistory } from "react-router"; describe("a hash history on a page with a tag", () => { let history: HashHistory; diff --git a/packages/router/__tests__/hash-test.ts b/packages/react-router/router/__tests__/hash-test.ts similarity index 97% rename from packages/router/__tests__/hash-test.ts rename to packages/react-router/router/__tests__/hash-test.ts index 60bae0b926..c5e116d794 100644 --- a/packages/router/__tests__/hash-test.ts +++ b/packages/react-router/router/__tests__/hash-test.ts @@ -2,8 +2,8 @@ import { JSDOM } from "jsdom"; -import type { HashHistory } from "@remix-run/router"; -import { createHashHistory } from "@remix-run/router"; +import type { HashHistory } from "react-router"; +import { createHashHistory } from "react-router"; import Listen from "./TestSequences/Listen"; import InitialLocationDefaultKey from "./TestSequences/InitialLocationDefaultKey"; diff --git a/packages/router/__tests__/interruptions-test.ts b/packages/react-router/router/__tests__/interruptions-test.ts similarity index 100% rename from packages/router/__tests__/interruptions-test.ts rename to packages/react-router/router/__tests__/interruptions-test.ts diff --git a/packages/router/__tests__/lazy-test.ts b/packages/react-router/router/__tests__/lazy-test.ts similarity index 100% rename from packages/router/__tests__/lazy-test.ts rename to packages/react-router/router/__tests__/lazy-test.ts diff --git a/packages/router/__tests__/memory-test.ts b/packages/react-router/router/__tests__/memory-test.ts similarity index 97% rename from packages/router/__tests__/memory-test.ts rename to packages/react-router/router/__tests__/memory-test.ts index e5233b50e3..67ff63b691 100644 --- a/packages/router/__tests__/memory-test.ts +++ b/packages/react-router/router/__tests__/memory-test.ts @@ -1,7 +1,7 @@ /* eslint-disable jest/expect-expect */ -import type { MemoryHistory } from "@remix-run/router"; -import { createMemoryHistory } from "@remix-run/router"; +import type { MemoryHistory } from "react-router"; +import { createMemoryHistory } from "react-router"; import Listen from "./TestSequences/Listen"; import InitialLocationHasKey from "./TestSequences/InitialLocationHasKey"; diff --git a/packages/router/__tests__/navigation-blocking-test.ts b/packages/react-router/router/__tests__/navigation-blocking-test.ts similarity index 100% rename from packages/router/__tests__/navigation-blocking-test.ts rename to packages/react-router/router/__tests__/navigation-blocking-test.ts diff --git a/packages/router/__tests__/navigation-test.ts b/packages/react-router/router/__tests__/navigation-test.ts similarity index 99% rename from packages/router/__tests__/navigation-test.ts rename to packages/react-router/router/__tests__/navigation-test.ts index 894da06535..bf67d5fdb7 100644 --- a/packages/router/__tests__/navigation-test.ts +++ b/packages/react-router/router/__tests__/navigation-test.ts @@ -169,11 +169,7 @@ describe("navigations", () => { }) ); expect(t.router.state.loaderData).toEqual({}); - expect(t.router.state.errors).toMatchInlineSnapshot(` - { - "foo": [SyntaxError: Unexpected token } in JSON at position 15], - } - `); + expect(String(t.router.state.errors.foo)).toMatch(/SyntaxError: /); }); it("bubbles errors when unwrapping Responses", async () => { @@ -204,11 +200,7 @@ describe("navigations", () => { }) ); expect(t.router.state.loaderData).toEqual({}); - expect(t.router.state.errors).toMatchInlineSnapshot(` - { - "root": [SyntaxError: Unexpected token } in JSON at position 15], - } - `); + expect(String(t.router.state.errors.root)).toMatch(/SyntaxError: /); }); it("does not fetch unchanging layout data", async () => { diff --git a/packages/router/__tests__/path-resolution-test.ts b/packages/react-router/router/__tests__/path-resolution-test.ts similarity index 100% rename from packages/router/__tests__/path-resolution-test.ts rename to packages/react-router/router/__tests__/path-resolution-test.ts diff --git a/packages/router/__tests__/redirects-test.ts b/packages/react-router/router/__tests__/redirects-test.ts similarity index 100% rename from packages/router/__tests__/redirects-test.ts rename to packages/react-router/router/__tests__/redirects-test.ts diff --git a/packages/router/__tests__/resolveTo-test.tsx b/packages/react-router/router/__tests__/resolveTo-test.tsx similarity index 93% rename from packages/router/__tests__/resolveTo-test.tsx rename to packages/react-router/router/__tests__/resolveTo-test.tsx index b36b2df0b0..85010e6c13 100644 --- a/packages/router/__tests__/resolveTo-test.tsx +++ b/packages/react-router/router/__tests__/resolveTo-test.tsx @@ -1,4 +1,4 @@ -import { resolveTo } from "@remix-run/router"; +import { resolveTo } from "react-router"; describe("resolveTo", () => { it('resolve path without mutating the "to" argument', () => { diff --git a/packages/router/__tests__/revalidate-test.ts b/packages/react-router/router/__tests__/revalidate-test.ts similarity index 100% rename from packages/router/__tests__/revalidate-test.ts rename to packages/react-router/router/__tests__/revalidate-test.ts diff --git a/packages/router/__tests__/route-fallback-test.ts b/packages/react-router/router/__tests__/route-fallback-test.ts similarity index 100% rename from packages/router/__tests__/route-fallback-test.ts rename to packages/react-router/router/__tests__/route-fallback-test.ts diff --git a/packages/router/__tests__/router-memory-test.ts b/packages/react-router/router/__tests__/router-memory-test.ts similarity index 100% rename from packages/router/__tests__/router-memory-test.ts rename to packages/react-router/router/__tests__/router-memory-test.ts diff --git a/packages/router/__tests__/router-test.ts b/packages/react-router/router/__tests__/router-test.ts similarity index 100% rename from packages/router/__tests__/router-test.ts rename to packages/react-router/router/__tests__/router-test.ts diff --git a/packages/router/__tests__/scroll-restoration-test.ts b/packages/react-router/router/__tests__/scroll-restoration-test.ts similarity index 100% rename from packages/router/__tests__/scroll-restoration-test.ts rename to packages/react-router/router/__tests__/scroll-restoration-test.ts diff --git a/packages/router/__tests__/setup.ts b/packages/react-router/router/__tests__/setup.ts similarity index 100% rename from packages/router/__tests__/setup.ts rename to packages/react-router/router/__tests__/setup.ts diff --git a/packages/router/__tests__/should-revalidate-test.ts b/packages/react-router/router/__tests__/should-revalidate-test.ts similarity index 100% rename from packages/router/__tests__/should-revalidate-test.ts rename to packages/react-router/router/__tests__/should-revalidate-test.ts diff --git a/packages/router/__tests__/ssr-test.ts b/packages/react-router/router/__tests__/ssr-test.ts similarity index 100% rename from packages/router/__tests__/ssr-test.ts rename to packages/react-router/router/__tests__/ssr-test.ts diff --git a/packages/router/__tests__/submission-test.ts b/packages/react-router/router/__tests__/submission-test.ts similarity index 100% rename from packages/router/__tests__/submission-test.ts rename to packages/react-router/router/__tests__/submission-test.ts diff --git a/packages/router/__tests__/utils/custom-matchers.ts b/packages/react-router/router/__tests__/utils/custom-matchers.ts similarity index 100% rename from packages/router/__tests__/utils/custom-matchers.ts rename to packages/react-router/router/__tests__/utils/custom-matchers.ts diff --git a/packages/router/__tests__/utils/data-router-setup.ts b/packages/react-router/router/__tests__/utils/data-router-setup.ts similarity index 99% rename from packages/router/__tests__/utils/data-router-setup.ts rename to packages/react-router/router/__tests__/utils/data-router-setup.ts index cc77d8f290..1bcd072a93 100644 --- a/packages/router/__tests__/utils/data-router-setup.ts +++ b/packages/react-router/router/__tests__/utils/data-router-setup.ts @@ -143,7 +143,6 @@ type SetupOpts = { initialEntries?: InitialEntry[]; initialIndex?: number; hydrationData?: HydrationState; - future?: FutureConfig; dataStrategy?: DataStrategyFunction; future?: Partial; }; diff --git a/packages/router/__tests__/utils/urlDataStrategy.ts b/packages/react-router/router/__tests__/utils/urlDataStrategy.ts similarity index 96% rename from packages/router/__tests__/utils/urlDataStrategy.ts rename to packages/react-router/router/__tests__/utils/urlDataStrategy.ts index 5acf3687d8..f35e707fec 100644 --- a/packages/router/__tests__/utils/urlDataStrategy.ts +++ b/packages/react-router/router/__tests__/utils/urlDataStrategy.ts @@ -1,7 +1,7 @@ import type { DataStrategyFunction, DataStrategyFunctionArgs, -} from "@remix-run/router"; +} from "react-router"; import { invariant } from "./utils"; export default async function urlDataStrategy({ diff --git a/packages/router/__tests__/utils/utils.ts b/packages/react-router/router/__tests__/utils/utils.ts similarity index 100% rename from packages/router/__tests__/utils/utils.ts rename to packages/react-router/router/__tests__/utils/utils.ts diff --git a/packages/router/__tests__/view-transition-test.ts b/packages/react-router/router/__tests__/view-transition-test.ts similarity index 100% rename from packages/router/__tests__/view-transition-test.ts rename to packages/react-router/router/__tests__/view-transition-test.ts diff --git a/packages/router/history.ts b/packages/react-router/router/history.ts similarity index 100% rename from packages/router/history.ts rename to packages/react-router/router/history.ts diff --git a/packages/router/index.ts b/packages/react-router/router/index.ts similarity index 100% rename from packages/router/index.ts rename to packages/react-router/router/index.ts diff --git a/packages/router/router.ts b/packages/react-router/router/router.ts similarity index 99% rename from packages/router/router.ts rename to packages/react-router/router/router.ts index cf693cc3b9..134b398d6a 100644 --- a/packages/router/router.ts +++ b/packages/react-router/router/router.ts @@ -2670,7 +2670,7 @@ export function createRouter(init: RouterInit): Router { } function markFetchRedirectsDone(): boolean { - let doneKeys = []; + let doneKeys: string[] = []; let updatedFetchers = false; for (let key of fetchRedirectIds) { let fetcher = state.fetchers.get(key); @@ -2686,7 +2686,7 @@ export function createRouter(init: RouterInit): Router { } function abortStaleFetchLoads(landedId: number): boolean { - let yeetedKeys = []; + let yeetedKeys: string[] = []; for (let [key, id] of fetchReloadIds) { if (id < landedId) { let fetcher = state.fetchers.get(key); diff --git a/packages/router/utils.ts b/packages/react-router/router/utils.ts similarity index 99% rename from packages/router/utils.ts rename to packages/react-router/router/utils.ts index 561421e777..45d008bc3f 100644 --- a/packages/router/utils.ts +++ b/packages/react-router/router/utils.ts @@ -515,7 +515,7 @@ export function matchRoutes< let branches = flattenRoutes(routes); rankRouteBranches(branches); - let matches = null; + let matches: AgnosticRouteMatch[] | null = null; for (let i = 0; matches == null && i < branches.length; ++i) { // Incoming pathnames are generally encoded from either window.location // or from router.navigate, but we want to match against the unencoded diff --git a/packages/router/.eslintrc b/packages/router/.eslintrc deleted file mode 100644 index 20b88a3051..0000000000 --- a/packages/router/.eslintrc +++ /dev/null @@ -1,10 +0,0 @@ -{ - "env": { - "browser": true, - "commonjs": true - }, - "rules": { - "strict": 0, - "no-restricted-syntax": ["error", "LogicalExpression[operator='??']"] - } -} diff --git a/packages/router/CHANGELOG.md b/packages/router/CHANGELOG.md deleted file mode 100644 index ac112bde1e..0000000000 --- a/packages/router/CHANGELOG.md +++ /dev/null @@ -1,716 +0,0 @@ -# `@remix-run/router` - -## 1.15.3 - -### Patch Changes - -- Fix a `future.v7_partialHydration` bug that would re-run loaders below the boundary on hydration if SSR loader errors bubbled to a parent boundary ([#11324](https://github.com/remix-run/react-router/pull/11324)) -- Fix a `future.v7_partialHydration` bug that would consider the router uninitialized if a route did not have a loader ([#11325](https://github.com/remix-run/react-router/pull/11325)) - -## 1.15.2 - -### Patch Changes - -- Preserve hydrated errors during partial hydration runs ([#11305](https://github.com/remix-run/react-router/pull/11305)) - -## 1.15.1 - -### Patch Changes - -- Fix encoding/decoding issues with pre-encoded dynamic parameter values ([#11199](https://github.com/remix-run/react-router/pull/11199)) - -## 1.15.0 - -### Minor Changes - -- Add a `createStaticHandler` `future.v7_throwAbortReason` flag to throw `request.signal.reason` (defaults to a `DOMException`) when a request is aborted instead of an `Error` such as `new Error("query() call aborted: GET /path")` ([#11104](https://github.com/remix-run/react-router/pull/11104)) - - - Please note that `DOMException` was added in Node v17 so you will not get a `DOMException` on Node 16 and below. - -### Patch Changes - -- Respect the `ErrorResponse` status code if passed to `getStaticContextFormError` ([#11213](https://github.com/remix-run/react-router/pull/11213)) - -## 1.14.2 - -### Patch Changes - -- Fix bug where dashes were not picked up in dynamic parameter names ([#11160](https://github.com/remix-run/react-router/pull/11160)) -- Do not attempt to deserialize empty JSON responses ([#11164](https://github.com/remix-run/react-router/pull/11164)) - -## 1.14.1 - -### Patch Changes - -- Fix bug with `route.lazy` not working correctly on initial SPA load when `v7_partialHydration` is specified ([#11121](https://github.com/remix-run/react-router/pull/11121)) -- Fix bug preventing revalidation from occurring for persisted fetchers unmounted during the `submitting` phase ([#11102](https://github.com/remix-run/react-router/pull/11102)) -- De-dup relative path logic in `resolveTo` ([#11097](https://github.com/remix-run/react-router/pull/11097)) - -## 1.14.0 - -### Minor Changes - -- Added a new `future.v7_partialHydration` future flag that enables partial hydration of a data router when Server-Side Rendering. This allows you to provide `hydrationData.loaderData` that has values for _some_ initially matched route loaders, but not all. When this flag is enabled, the router will call `loader` functions for routes that do not have hydration loader data during `router.initialize()`, and it will render down to the deepest provided `HydrateFallback` (up to the first route without hydration data) while it executes the unhydrated routes. ([#11033](https://github.com/remix-run/react-router/pull/11033)) - - For example, the following router has a `root` and `index` route, but only provided `hydrationData.loaderData` for the `root` route. Because the `index` route has a `loader`, we need to run that during initialization. With `future.v7_partialHydration` specified, `` will render the `RootComponent` (because it has data) and then the `IndexFallback` (since it does not have data). Once `indexLoader` finishes, application will update and display `IndexComponent`. - - ```jsx - let router = createBrowserRouter( - [ - { - id: "root", - path: "/", - loader: rootLoader, - Component: RootComponent, - Fallback: RootFallback, - children: [ - { - id: "index", - index: true, - loader: indexLoader, - Component: IndexComponent, - HydrateFallback: IndexFallback, - }, - ], - }, - ], - { - future: { - v7_partialHydration: true, - }, - hydrationData: { - loaderData: { - root: { message: "Hydrated from Root!" }, - }, - }, - } - ); - ``` - - If the above example did not have an `IndexFallback`, then `RouterProvider` would instead render the `RootFallback` while it executed the `indexLoader`. - - **Note:** When `future.v7_partialHydration` is provided, the `` prop is ignored since you can move it to a `Fallback` on your top-most route. The `fallbackElement` prop will be removed in React Router v7 when `v7_partialHydration` behavior becomes the standard behavior. - -- Add a new `future.v7_relativeSplatPath` flag to implement a breaking bug fix to relative routing when inside a splat route. ([#11087](https://github.com/remix-run/react-router/pull/11087)) - - This fix was originally added in [#10983](https://github.com/remix-run/react-router/issues/10983) and was later reverted in [#11078](https://github.com/remix-run/react-router/pull/11078) because it was determined that a large number of existing applications were relying on the buggy behavior (see [#11052](https://github.com/remix-run/react-router/issues/11052)) - - **The Bug** - The buggy behavior is that without this flag, the default behavior when resolving relative paths is to _ignore_ any splat (`*`) portion of the current route path. - - **The Background** - This decision was originally made thinking that it would make the concept of nested different sections of your apps in `` easier if relative routing would _replace_ the current splat: - - ```jsx - - - } /> - } /> - - - ``` - - Any paths like `/dashboard`, `/dashboard/team`, `/dashboard/projects` will match the `Dashboard` route. The dashboard component itself can then render nested ``: - - ```jsx - function Dashboard() { - return ( -
-

Dashboard

- - - - } /> - } /> - } /> - -
- ); - } - ``` - - Now, all links and route paths are relative to the router above them. This makes code splitting and compartmentalizing your app really easy. You could render the `Dashboard` as its own independent app, or embed it into your large app without making any changes to it. - - **The Problem** - - The problem is that this concept of ignoring part of a path breaks a lot of other assumptions in React Router - namely that `"."` always means the current location pathname for that route. When we ignore the splat portion, we start getting invalid paths when using `"."`: - - ```jsx - // If we are on URL /dashboard/team, and we want to link to /dashboard/team: - function DashboardTeam() { - // ❌ This is broken and results in - return A broken link to the Current URL; - - // ✅ This is fixed but super unintuitive since we're already at /dashboard/team! - return A broken link to the Current URL; - } - ``` - - We've also introduced an issue that we can no longer move our `DashboardTeam` component around our route hierarchy easily - since it behaves differently if we're underneath a non-splat route, such as `/dashboard/:widget`. Now, our `"."` links will, properly point to ourself _inclusive of the dynamic param value_ so behavior will break from it's corresponding usage in a `/dashboard/*` route. - - Even worse, consider a nested splat route configuration: - - ```jsx - - - - } /> - - - - ``` - - Now, a `` and a `` inside the `Dashboard` component go to the same place! That is definitely not correct! - - Another common issue arose in Data Routers (and Remix) where any `
` should post to it's own route `action` if you the user doesn't specify a form action: - - ```jsx - let router = createBrowserRouter({ - path: "/dashboard", - children: [ - { - path: "*", - action: dashboardAction, - Component() { - // ❌ This form is broken! It throws a 405 error when it submits because - // it tries to submit to /dashboard (without the splat value) and the parent - // `/dashboard` route doesn't have an action - return ...
; - }, - }, - ], - }); - ``` - - This is just a compounded issue from the above because the default location for a `Form` to submit to is itself (`"."`) - and if we ignore the splat portion, that now resolves to the parent route. - - **The Solution** - If you are leveraging this behavior, it's recommended to enable the future flag, move your splat to it's own route, and leverage `../` for any links to "sibling" pages: - - ```jsx - - - - } /> - - - - - function Dashboard() { - return ( -
-

Dashboard

- - - - } /> - } /> - } /> - -
- ); - } - ``` - - This way, `.` means "the full current pathname for my route" in all cases (including static, dynamic, and splat routes) and `..` always means "my parents pathname". - -### Patch Changes - -- Catch and bubble errors thrown when trying to unwrap responses from `loader`/`action` functions ([#11061](https://github.com/remix-run/react-router/pull/11061)) -- Fix `relative="path"` issue when rendering `Link`/`NavLink` outside of matched routes ([#11062](https://github.com/remix-run/react-router/pull/11062)) - -## 1.13.1 - -### Patch Changes - -- Revert the `useResolvedPath` fix for splat routes due to a large number of applications that were relying on the buggy behavior (see ). We plan to re-introduce this fix behind a future flag in the next minor version. ([#11078](https://github.com/remix-run/react-router/pull/11078)) - -## 1.13.0 - -### Minor Changes - -- Export the `PathParam` type from the public API ([#10719](https://github.com/remix-run/react-router/pull/10719)) - -### Patch Changes - -- Fix bug with `resolveTo` in splat routes ([#11045](https://github.com/remix-run/react-router/pull/11045)) - - This is a follow up to [#10983](https://github.com/remix-run/react-router/pull/10983) to handle the few other code paths using `getPathContributingMatches` - - This removes the `UNSAFE_getPathContributingMatches` export from `@remix-run/router` since we no longer need this in the `react-router`/`react-router-dom` layers -- Do not revalidate unmounted fetchers when `v7_fetcherPersist` is enabled ([#11044](https://github.com/remix-run/react-router/pull/11044)) - -## 1.12.0 - -### Minor Changes - -- Add `unstable_flushSync` option to `router.navigate` and `router.fetch` to tell the React Router layer to opt-out of `React.startTransition` and into `ReactDOM.flushSync` for state updates ([#11005](https://github.com/remix-run/react-router/pull/11005)) - -### Patch Changes - -- Fix `relative="path"` bug where relative path calculations started from the full location pathname, instead of from the current contextual route pathname. ([#11006](https://github.com/remix-run/react-router/pull/11006)) - - ```jsx - - }> - - - ; - - function Component() { - return ( - <> - {/* This is now correctly relative to /a/b, not /a/b/c */} - - - - ); - } - ``` - -## 1.11.0 - -### Minor Changes - -- Add a new `future.v7_fetcherPersist` flag to the `@remix-run/router` to change the persistence behavior of fetchers when `router.deleteFetcher` is called. Instead of being immediately cleaned up, fetchers will persist until they return to an `idle` state ([RFC](https://github.com/remix-run/remix/discussions/7698)) ([#10962](https://github.com/remix-run/react-router/pull/10962)) - - - This is sort of a long-standing bug fix as the `useFetchers()` API was always supposed to only reflect **in-flight** fetcher information for pending/optimistic UI -- it was not intended to reflect fetcher data or hang onto fetchers after they returned to an `idle` state - - Keep an eye out for the following specific behavioral changes when opting into this flag and check your app for compatibility: - - Fetchers that complete _while still mounted_ will no longer appear in `useFetchers()`. They served effectively no purpose in there since you can access the data via `useFetcher().data`). - - Fetchers that previously unmounted _while in-flight_ will not be immediately aborted and will instead be cleaned up once they return to an `idle` state. They will remain exposed via `useFetchers` while in-flight so you can still access pending/optimistic data after unmount. - -- When `v7_fetcherPersist` is enabled, the router now performs ref-counting on fetcher keys via `getFetcher`/`deleteFetcher` so it knows when a given fetcher is totally unmounted from the UI ([#10977](https://github.com/remix-run/react-router/pull/10977)) - - - Once a fetcher has been totally unmounted, we can ignore post-processing of a persisted fetcher result such as a redirect or an error - - The router will also pass a new `deletedFetchers` array to the subscriber callbacks so that the UI layer can remove associated fetcher data - -- Add support for optional path segments in `matchPath` ([#10768](https://github.com/remix-run/react-router/pull/10768)) - -### Patch Changes - -- Fix `router.getFetcher`/`router.deleteFetcher` type definitions which incorrectly specified `key` as an optional parameter ([#10960](https://github.com/remix-run/react-router/pull/10960)) - -## 1.10.0 - -### Minor Changes - -- Add experimental support for the [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/ViewTransition) by allowing users to opt-into view transitions on navigations via the new `unstable_viewTransition` option to `router.navigate` ([#10916](https://github.com/remix-run/react-router/pull/10916)) - -### Patch Changes - -- Allow 404 detection to leverage root route error boundary if path contains a URL segment ([#10852](https://github.com/remix-run/react-router/pull/10852)) -- Fix `ErrorResponse` type to avoid leaking internal field ([#10876](https://github.com/remix-run/react-router/pull/10876)) - -## 1.9.0 - -### Minor Changes - -- In order to move towards stricter TypeScript support in the future, we're aiming to replace current usages of `any` with `unknown` on exposed typings for user-provided data. To do this in Remix v2 without introducing breaking changes in React Router v6, we have added generics to a number of shared types. These continue to default to `any` in React Router and are overridden with `unknown` in Remix. In React Router v7 we plan to move these to `unknown` as a breaking change. ([#10843](https://github.com/remix-run/react-router/pull/10843)) - - `Location` now accepts a generic for the `location.state` value - - `ActionFunctionArgs`/`ActionFunction`/`LoaderFunctionArgs`/`LoaderFunction` now accept a generic for the `context` parameter (only used in SSR usages via `createStaticHandler`) - - The return type of `useMatches` (now exported as `UIMatch`) accepts generics for `match.data` and `match.handle` - both of which were already set to `unknown` -- Move the `@private` class export `ErrorResponse` to an `UNSAFE_ErrorResponseImpl` export since it is an implementation detail and there should be no construction of `ErrorResponse` instances in userland. This frees us up to export a `type ErrorResponse` which correlates to an instance of the class via `InstanceType`. Userland code should only ever be using `ErrorResponse` as a type and should be type-narrowing via `isRouteErrorResponse`. ([#10811](https://github.com/remix-run/react-router/pull/10811)) -- Export `ShouldRevalidateFunctionArgs` interface ([#10797](https://github.com/remix-run/react-router/pull/10797)) -- Removed private/internal APIs only required for the Remix v1 backwards compatibility layer and no longer needed in Remix v2 (`_isFetchActionRedirect`, `_hasFetcherDoneAnything`) ([#10715](https://github.com/remix-run/react-router/pull/10715)) - -### Patch Changes - -- Add method/url to error message on aborted `query`/`queryRoute` calls ([#10793](https://github.com/remix-run/react-router/pull/10793)) -- Fix a race-condition with loader/action-thrown errors on `route.lazy` routes ([#10778](https://github.com/remix-run/react-router/pull/10778)) -- Fix type for `actionResult` on the arguments object passed to `shouldRevalidate` ([#10779](https://github.com/remix-run/react-router/pull/10779)) - -## 1.8.0 - -### Minor Changes - -- Add's a new `redirectDocument()` function which allows users to specify that a redirect from a `loader`/`action` should trigger a document reload (via `window.location`) instead of attempting to navigate to the redirected location via React Router ([#10705](https://github.com/remix-run/react-router/pull/10705)) - -### Patch Changes - -- Fix an issue in `queryRoute` that was not always identifying thrown `Response` instances ([#10717](https://github.com/remix-run/react-router/pull/10717)) -- Ensure hash history always includes a leading slash on hash pathnames ([#10753](https://github.com/remix-run/react-router/pull/10753)) - -## 1.7.2 - -### Patch Changes - -- Trigger an error if a `defer` promise resolves/rejects with `undefined` in order to match the behavior of loaders and actions which must return a value or `null` ([#10690](https://github.com/remix-run/react-router/pull/10690)) -- Properly handle fetcher redirects interrupted by normal navigations ([#10674](https://github.com/remix-run/react-router/pull/10674), [#10709](https://github.com/remix-run/react-router/pull/10709)) -- Initial-load fetchers should not automatically revalidate on GET navigations ([#10688](https://github.com/remix-run/react-router/pull/10688)) -- Enhance the return type of `Route.lazy` to prohibit returning an empty object ([#10634](https://github.com/remix-run/react-router/pull/10634)) - -## 1.7.1 - -### Patch Changes - -- Fix issues with reused blockers on subsequent navigations ([#10656](https://github.com/remix-run/react-router/pull/10656)) - -## 1.7.0 - -### Minor Changes - -- Add support for `application/json` and `text/plain` encodings for `router.navigate`/`router.fetch` submissions. To leverage these encodings, pass your data in a `body` parameter and specify the desired `formEncType`: ([#10413](https://github.com/remix-run/react-router/pull/10413)) - - ```js - // By default, the encoding is "application/x-www-form-urlencoded" - router.navigate("/", { - formMethod: "post", - body: { key: "value" }, - }); - - async function action({ request }) { - // await request.formData() => FormData instance with entry [key=value] - } - ``` - - ```js - // Pass `formEncType` to opt-into a different encoding (json) - router.navigate("/", { - formMethod: "post", - formEncType: "application/json", - body: { key: "value" }, - }); - - async function action({ request }) { - // await request.json() => { key: "value" } - } - ``` - - ```js - // Pass `formEncType` to opt-into a different encoding (text) - router.navigate("/", { - formMethod: "post", - formEncType: "text/plain", - body: "Text submission", - }); - - async function action({ request }) { - // await request.text() => "Text submission" - } - ``` - -### Patch Changes - -- Call `window.history.pushState/replaceState` before updating React Router state (instead of after) so that `window.location` matches `useLocation` during synchronous React 17 rendering ([#10448](https://github.com/remix-run/react-router/pull/10448)) - - ⚠️ However, generally apps should not be relying on `window.location` and should always reference `useLocation` when possible, as `window.location` will not be in sync 100% of the time (due to `popstate` events, concurrent mode, etc.) -- Strip `basename` from the `location` provided to `` to match the `useLocation` behavior ([#10550](https://github.com/remix-run/react-router/pull/10550)) -- Avoid calling `shouldRevalidate` for fetchers that have not yet completed a data load ([#10623](https://github.com/remix-run/react-router/pull/10623)) -- Fix `unstable_useBlocker` key issues in `StrictMode` ([#10573](https://github.com/remix-run/react-router/pull/10573)) -- Upgrade `typescript` to 5.1 ([#10581](https://github.com/remix-run/react-router/pull/10581)) - -## 1.6.3 - -### Patch Changes - -- Allow fetcher revalidations to complete if submitting fetcher is deleted ([#10535](https://github.com/remix-run/react-router/pull/10535)) -- Re-throw `DOMException` (`DataCloneError`) when attempting to perform a `PUSH` navigation with non-serializable state. ([#10427](https://github.com/remix-run/react-router/pull/10427)) -- Ensure revalidations happen when hash is present ([#10516](https://github.com/remix-run/react-router/pull/10516)) -- upgrade jest and jsdom ([#10453](https://github.com/remix-run/react-router/pull/10453)) - -## 1.6.2 - -### Patch Changes - -- Fix HMR-driven error boundaries by properly reconstructing new routes and `manifest` in `\_internalSetRoutes` ([#10437](https://github.com/remix-run/react-router/pull/10437)) -- Fix bug where initial data load would not kick off when hash is present ([#10493](https://github.com/remix-run/react-router/pull/10493)) - -## 1.6.1 - -### Patch Changes - -- Fix `basename` handling when navigating without a path ([#10433](https://github.com/remix-run/react-router/pull/10433)) -- "Same hash" navigations no longer re-run loaders to match browser behavior (i.e. `/path#hash -> /path#hash`) ([#10408](https://github.com/remix-run/react-router/pull/10408)) - -## 1.6.0 - -### Minor Changes - -- Enable relative routing in the `@remix-run/router` when providing a source route ID from which the path is relative to: ([#10336](https://github.com/remix-run/react-router/pull/10336)) - - - Example: `router.navigate("../path", { fromRouteId: "some-route" })`. - - This also applies to `router.fetch` which already receives a source route ID - -- Introduce a new `@remix-run/router` `future.v7_prependBasename` flag to enable `basename` prefixing to all paths coming into `router.navigate` and `router.fetch`. - - - Previously the `basename` was prepended in the React Router layer, but now that relative routing is being handled by the router we need prepend the `basename` _after_ resolving any relative paths - - This also enables `basename` support in `useFetcher` as well - -### Patch Changes - -- Enhance `LoaderFunction`/`ActionFunction` return type to prevent `undefined` from being a valid return value ([#10267](https://github.com/remix-run/react-router/pull/10267)) -- Ensure proper 404 error on `fetcher.load` call to a route without a `loader` ([#10345](https://github.com/remix-run/react-router/pull/10345)) -- Deprecate the `createRouter` `detectErrorBoundary` option in favor of the new `mapRouteProperties` option for converting a framework-agnostic route to a framework-aware route. This allows us to set more than just the `hasErrorBoundary` property during route pre-processing, and is now used for mapping `Component -> element` and `ErrorBoundary -> errorElement` in `react-router`. ([#10287](https://github.com/remix-run/react-router/pull/10287)) -- Fixed a bug where fetchers were incorrectly attempting to revalidate on search params changes or routing to the same URL (using the same logic for route `loader` revalidations). However, since fetchers have a static href, they should only revalidate on `action` submissions or `router.revalidate` calls. ([#10344](https://github.com/remix-run/react-router/pull/10344)) -- Decouple `AbortController` usage between revalidating fetchers and the thing that triggered them such that the unmount/deletion of a revalidating fetcher doesn't impact the ongoing triggering navigation/revalidation ([#10271](https://github.com/remix-run/react-router/pull/10271)) - -## 1.5.0 - -### Minor Changes - -- Added support for [**Future Flags**](https://reactrouter.com/en/main/guides/api-development-strategy) in React Router. The first flag being introduced is `future.v7_normalizeFormMethod` which will normalize the exposed `useNavigation()/useFetcher()` `formMethod` fields as uppercase HTTP methods to align with the `fetch()` behavior. ([#10207](https://github.com/remix-run/react-router/pull/10207)) - - - When `future.v7_normalizeFormMethod === false` (default v6 behavior), - - `useNavigation().formMethod` is lowercase - - `useFetcher().formMethod` is lowercase - - When `future.v7_normalizeFormMethod === true`: - - `useNavigation().formMethod` is uppercase - - `useFetcher().formMethod` is uppercase - -### Patch Changes - -- Provide fetcher submission to `shouldRevalidate` if the fetcher action redirects ([#10208](https://github.com/remix-run/react-router/pull/10208)) -- Properly handle `lazy()` errors during router initialization ([#10201](https://github.com/remix-run/react-router/pull/10201)) -- Remove `instanceof` check for `DeferredData` to be resilient to ESM/CJS boundaries in SSR bundling scenarios ([#10247](https://github.com/remix-run/react-router/pull/10247)) -- Update to latest `@remix-run/web-fetch@4.3.3` ([#10216](https://github.com/remix-run/react-router/pull/10216)) - -## 1.4.0 - -### Minor Changes - -- **Introducing Lazy Route Modules!** ([#10045](https://github.com/remix-run/react-router/pull/10045)) - - In order to keep your application bundles small and support code-splitting of your routes, we've introduced a new `lazy()` route property. This is an async function that resolves the non-route-matching portions of your route definition (`loader`, `action`, `element`/`Component`, `errorElement`/`ErrorBoundary`, `shouldRevalidate`, `handle`). - - Lazy routes are resolved on initial load and during the `loading` or `submitting` phase of a navigation or fetcher call. You cannot lazily define route-matching properties (`path`, `index`, `children`) since we only execute your lazy route functions after we've matched known routes. - - Your `lazy` functions will typically return the result of a dynamic import. - - ```jsx - // In this example, we assume most folks land on the homepage so we include that - // in our critical-path bundle, but then we lazily load modules for /a and /b so - // they don't load until the user navigates to those routes - let routes = createRoutesFromElements( - }> - } /> - import("./a")} /> - import("./b")} /> - - ); - ``` - - Then in your lazy route modules, export the properties you want defined for the route: - - ```jsx - export async function loader({ request }) { - let data = await fetchData(request); - return json(data); - } - - // Export a `Component` directly instead of needing to create a React Element from it - export function Component() { - let data = useLoaderData(); - - return ( - <> -

You made it!

-

{data}

- - ); - } - - // Export an `ErrorBoundary` directly instead of needing to create a React Element from it - export function ErrorBoundary() { - let error = useRouteError(); - return isRouteErrorResponse(error) ? ( -

- {error.status} {error.statusText} -

- ) : ( -

{error.message || error}

- ); - } - ``` - - An example of this in action can be found in the [`examples/lazy-loading-router-provider`](https://github.com/remix-run/react-router/tree/main/examples/lazy-loading-router-provider) directory of the repository. - - 🙌 Huge thanks to @rossipedia for the [Initial Proposal](https://github.com/remix-run/react-router/discussions/9826) and [POC Implementation](https://github.com/remix-run/react-router/pull/9830). - -### Patch Changes - -- Fix `generatePath` incorrectly applying parameters in some cases ([#10078](https://github.com/remix-run/react-router/pull/10078)) - -## 1.3.3 - -### Patch Changes - -- Correctly perform a hard redirect for same-origin absolute URLs outside of the router `basename` ([#10076](https://github.com/remix-run/react-router/pull/10076)) -- Ensure status code and headers are maintained for `defer` loader responses in `createStaticHandler`'s `query()` method ([#10077](https://github.com/remix-run/react-router/pull/10077)) -- Change `invariant` to an `UNSAFE_invariant` export since it's only intended for internal use ([#10066](https://github.com/remix-run/react-router/pull/10066)) -- Add internal API for custom HMR implementations ([#9996](https://github.com/remix-run/react-router/pull/9996)) - -## 1.3.2 - -### Patch Changes - -- Remove inaccurate console warning for POP navigations and update active blocker logic ([#10030](https://github.com/remix-run/react-router/pull/10030)) -- Only check for differing origin on absolute URL redirects ([#10033](https://github.com/remix-run/react-router/pull/10033)) - -## 1.3.1 - -### Patch Changes - -- Fixes 2 separate issues for revalidating fetcher `shouldRevalidate` calls ([#9948](https://github.com/remix-run/react-router/pull/9948)) - - The `shouldRevalidate` function was only being called for _explicit_ revalidation scenarios (after a mutation, manual `useRevalidator` call, or an `X-Remix-Revalidate` header used for cookie setting in Remix). It was not properly being called on _implicit_ revalidation scenarios that also apply to navigation `loader` revalidation, such as a change in search params or clicking a link for the page we're already on. It's now correctly called in those additional scenarios. - - The parameters being passed were incorrect and inconsistent with one another since the `current*`/`next*` parameters reflected the static `fetcher.load` URL (and thus were identical). Instead, they should have reflected the the navigation that triggered the revalidation (as the `form*` parameters did). These parameters now correctly reflect the triggering navigation. -- Respect `preventScrollReset` on `` ([#9963](https://github.com/remix-run/react-router/pull/9963)) -- Do not short circuit on hash change only mutation submissions ([#9944](https://github.com/remix-run/react-router/pull/9944)) -- Remove `instanceof` check from `isRouteErrorResponse` to avoid bundling issues on the server ([#9930](https://github.com/remix-run/react-router/pull/9930)) -- Fix navigation for hash routers on manual URL changes ([#9980](https://github.com/remix-run/react-router/pull/9980)) -- Detect when a `defer` call only contains critical data and remove the `AbortController` ([#9965](https://github.com/remix-run/react-router/pull/9965)) -- Send the name as the value when url-encoding `File` `FormData` entries ([#9867](https://github.com/remix-run/react-router/pull/9867)) - -## 1.3.0 - -### Minor Changes - -- Added support for navigation blocking APIs ([#9709](https://github.com/remix-run/react-router/pull/9709)) -- Expose deferred information from `createStaticHandler` ([#9760](https://github.com/remix-run/react-router/pull/9760)) - -### Patch Changes - -- Improved absolute redirect url detection in actions/loaders ([#9829](https://github.com/remix-run/react-router/pull/9829)) -- Fix URL creation with memory histories ([#9814](https://github.com/remix-run/react-router/pull/9814)) -- Fix `generatePath` when optional params are present ([#9764](https://github.com/remix-run/react-router/pull/9764)) -- Fix scroll reset if a submission redirects ([#9886](https://github.com/remix-run/react-router/pull/9886)) -- Fix 404 bug with same-origin absolute redirects ([#9913](https://github.com/remix-run/react-router/pull/9913)) -- Support `OPTIONS` requests in `staticHandler.queryRoute` ([#9914](https://github.com/remix-run/react-router/pull/9914)) - -## 1.2.1 - -### Patch Changes - -- Include submission info in `shouldRevalidate` on action redirects ([#9777](https://github.com/remix-run/react-router/pull/9777), [#9782](https://github.com/remix-run/react-router/pull/9782)) -- Reset `actionData` on action redirect to current location ([#9772](https://github.com/remix-run/react-router/pull/9772)) - -## 1.2.0 - -### Minor Changes - -- Remove `unstable_` prefix from `createStaticHandler`/`createStaticRouter`/`StaticRouterProvider` ([#9738](https://github.com/remix-run/react-router/pull/9738)) - -### Patch Changes - -- Fix explicit `replace` on submissions and `PUSH` on submission to new paths ([#9734](https://github.com/remix-run/react-router/pull/9734)) -- Fix a few bugs where loader/action data wasn't properly cleared on errors ([#9735](https://github.com/remix-run/react-router/pull/9735)) -- Prevent `useLoaderData` usage in `errorElement` ([#9735](https://github.com/remix-run/react-router/pull/9735)) -- Skip initial scroll restoration for SSR apps with `hydrationData` ([#9664](https://github.com/remix-run/react-router/pull/9664)) - -## 1.1.0 - -This release introduces support for [Optional Route Segments](https://github.com/remix-run/react-router/issues/9546). Now, adding a `?` to the end of any path segment will make that entire segment optional. This works for both static segments and dynamic parameters. - -**Optional Params Examples** - -- Path `lang?/about` will match: - - `/:lang/about` - - `/about` -- Path `/multistep/:widget1?/widget2?/widget3?` will match: - - `/multistep` - - `/multistep/:widget1` - - `/multistep/:widget1/:widget2` - - `/multistep/:widget1/:widget2/:widget3` - -**Optional Static Segment Example** - -- Path `/home?` will match: - - `/` - - `/home` -- Path `/fr?/about` will match: - - `/about` - - `/fr/about` - -### Minor Changes - -- Allows optional routes and optional static segments ([#9650](https://github.com/remix-run/react-router/pull/9650)) - -### Patch Changes - -- Stop incorrectly matching on partial named parameters, i.e. ``, to align with how splat parameters work. If you were previously relying on this behavior then it's recommended to extract the static portion of the path at the `useParams` call site: ([#9506](https://github.com/remix-run/react-router/pull/9506)) - -```jsx -// Old behavior at URL /prefix-123 - }> - -function Comp() { - let params = useParams(); // { id: '123' } - let id = params.id; // "123" - ... -} - -// New behavior at URL /prefix-123 - }> - -function Comp() { - let params = useParams(); // { id: 'prefix-123' } - let id = params.id.replace(/^prefix-/, ''); // "123" - ... -} -``` - -- Persist `headers` on `loader` `request`'s after SSR document `action` request ([#9721](https://github.com/remix-run/react-router/pull/9721)) -- Fix requests sent to revalidating loaders so they reflect a GET request ([#9660](https://github.com/remix-run/react-router/pull/9660)) -- Fix issue with deeply nested optional segments ([#9727](https://github.com/remix-run/react-router/pull/9727)) -- GET forms now expose a submission on the loading navigation ([#9695](https://github.com/remix-run/react-router/pull/9695)) -- Fix error boundary tracking for multiple errors bubbling to the same boundary ([#9702](https://github.com/remix-run/react-router/pull/9702)) - -## 1.0.5 - -### Patch Changes - -- Fix requests sent to revalidating loaders so they reflect a `GET` request ([#9680](https://github.com/remix-run/react-router/pull/9680)) -- Remove `instanceof Response` checks in favor of `isResponse` ([#9690](https://github.com/remix-run/react-router/pull/9690)) -- Fix `URL` creation in Cloudflare Pages or other non-browser-environments ([#9682](https://github.com/remix-run/react-router/pull/9682), [#9689](https://github.com/remix-run/react-router/pull/9689)) -- Add `requestContext` support to static handler `query`/`queryRoute` ([#9696](https://github.com/remix-run/react-router/pull/9696)) - - Note that the unstable API of `queryRoute(path, routeId)` has been changed to `queryRoute(path, { routeId, requestContext })` - -## 1.0.4 - -### Patch Changes - -- Throw an error if an `action`/`loader` function returns `undefined` as revalidations need to know whether the loader has previously been executed. `undefined` also causes issues during SSR stringification for hydration. You should always ensure you `loader`/`action` returns a value, and you may return `null` if you don't wish to return anything. ([#9511](https://github.com/remix-run/react-router/pull/9511)) -- Properly handle redirects to external domains ([#9590](https://github.com/remix-run/react-router/pull/9590), [#9654](https://github.com/remix-run/react-router/pull/9654)) -- Preserve the HTTP method on 307/308 redirects ([#9597](https://github.com/remix-run/react-router/pull/9597)) -- Support `basename` in static data routers ([#9591](https://github.com/remix-run/react-router/pull/9591)) -- Enhanced `ErrorResponse` bodies to contain more descriptive text in internal 403/404/405 scenarios - -## 1.0.3 - -### Patch Changes - -- Fix hrefs generated when using `createHashRouter` ([#9409](https://github.com/remix-run/react-router/pull/9409)) -- fix encoding/matching issues with special chars ([#9477](https://github.com/remix-run/react-router/pull/9477), [#9496](https://github.com/remix-run/react-router/pull/9496)) -- Support `basename` and relative routing in `loader`/`action` redirects ([#9447](https://github.com/remix-run/react-router/pull/9447)) -- Ignore pathless layout routes when looking for proper submission `action` function ([#9455](https://github.com/remix-run/react-router/pull/9455)) -- properly support `index` routes with a `path` in `useResolvedPath` ([#9486](https://github.com/remix-run/react-router/pull/9486)) -- Add UMD build for `@remix-run/router` ([#9446](https://github.com/remix-run/react-router/pull/9446)) -- fix `createURL` in local file execution in Firefox ([#9464](https://github.com/remix-run/react-router/pull/9464)) -- Updates to `unstable_createStaticHandler` for incorporating into Remix ([#9482](https://github.com/remix-run/react-router/pull/9482), [#9465](https://github.com/remix-run/react-router/pull/9465)) - -## 1.0.2 - -### Patch Changes - -- Reset `actionData` after a successful action redirect ([#9334](https://github.com/remix-run/react-router/pull/9334)) -- Update `matchPath` to avoid false positives on dash-separated segments ([#9300](https://github.com/remix-run/react-router/pull/9300)) -- If an index route has children, it will result in a runtime error. We have strengthened our `RouteObject`/`RouteProps` types to surface the error in TypeScript. ([#9366](https://github.com/remix-run/react-router/pull/9366)) - -## 1.0.1 - -### Patch Changes - -- Preserve state from `initialEntries` ([#9288](https://github.com/remix-run/react-router/pull/9288)) -- Preserve `?index` for fetcher get submissions to index routes ([#9312](https://github.com/remix-run/react-router/pull/9312)) - -## 1.0.0 - -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`. - -For an overview of the features provided by `react-router`, we recommend you go check out the [docs](https://reactrouter.com), especially the [feature overview](https://reactrouter.com/start/overview) and the [tutorial](https://reactrouter.com/start/tutorial). - -For an overview of the features provided by `@remix-run/router`, please check out the [`README`](./README.md). diff --git a/packages/router/README.md b/packages/router/README.md deleted file mode 100644 index 1c8536de0d..0000000000 --- a/packages/router/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# Remix Router - -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` - you should have everything you need in `react-router-dom` (or `react-router`/`react-router-native` if you're not rendering in the browser). All of those packages should re-export everything you would otherwise need from `@remix-run/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 - -A Router instance can be created using `createRouter`: - -```js -// Create and initialize a router. "initialize" contains all side effects -// including history listeners and kicking off the initial data fetch -let router = createRouter({ - // Required properties - routes: [{ - path: '/', - loader: ({ request, params }) => { /* ... */ }, - children: [{ - path: 'home', - loader: ({ request, params }) => { /* ... */ }, - }] - }, - history: createBrowserHistory(), - - // Optional properties - basename, // Base path - mapRouteProperties, // Map framework-agnostic routes to framework-aware routes - future, // Future flags - hydrationData, // Hydration data if using server-side-rendering -}).initialize(); -``` - -Internally, the Router represents the state in an object of the following format, which is available through `router.state`. You can also register a subscriber of the signature `(state: RouterState) => void` to execute when the state updates via `router.subscribe()`; - -```ts -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 - historyAction: Action; - // The current location of the router. During a navigation this reflects - // the "old" location and is updated upon completion of the navigation - location: Location; - // The current set of route matches - matches: DataRouteMatch[]; - // The state of the current navigation - navigation: Navigation; - // The state of any in-progress router.revalidate() calls - revalidation: RevalidationState; - // Data from the loaders for the current matches - loaderData: RouteData; - // Data from the action for the current matches - actionData: RouteData | null; - // Errors thrown from loaders/actions for the current matches - errors: RouteData | null; - // Map of all active fetchers - fetchers: Map; - // 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; -} -``` - -### Navigations - -All navigations are done through the `router.navigate` API which is overloaded to support different types of navigations: - -```js -// Link navigation (pushes onto the history stack by default) -router.navigate("/page"); - -// Link navigation (replacing the history stack) -router.navigate("/page", { replace: true }); - -// Pop navigation (moving backward/forward in the history stack) -router.navigate(-1); - -// Form submission navigation -let formData = new FormData(); -formData.append(key, value); -router.navigate("/page", { - formMethod: "post", - formData, -}); - -// Relative routing from a source routeId -router.navigate("../../somewhere", { - fromRouteId: "active-route-id", -}); -``` - -### Fetchers - -Fetchers are a mechanism to call loaders/actions without triggering a navigation, and are done through the `router.fetch()` API. All fetch calls require a unique key to identify the fetcher. - -```js -// Execute the loader for /page -router.fetch("key", "/page"); - -// Submit to the action for /page -let formData = new FormData(); -formData.append(key, value); -router.fetch("key", "/page", { - formMethod: "post", - formData, -}); -``` - -### 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. - -### Future Flags - -We use _Future Flags_ in the router to help us introduce breaking changes in an opt-in fashion ahead of major releases. Please check out the [blog post][future-flags-post] and [React Router Docs][api-development-strategy] for more information on this process. The currently available future flags in `@remix-run/router` are: - -| Flag | Description | -| ------------------------ | ------------------------------------------------------------------------- | -| `v7_normalizeFormMethod` | Normalize `useNavigation().formMethod` to be an uppercase HTTP Method | -| `v7_prependBasename` | Prepend the `basename` to incoming `router.navigate`/`router.fetch` paths | - -[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 -[api-development-strategy]: https://reactrouter.com/en/main/guides/api-development-strategy -[future-flags-post]: https://remix.run/blog/future-flags diff --git a/packages/router/jest.config.js b/packages/router/jest.config.js deleted file mode 100644 index 204ad4c406..0000000000 --- a/packages/router/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -/** @type {import('jest').Config} */ -module.exports = { - ...require("../../jest/jest.config.shared"), - testEnvironment: "jsdom", -}; diff --git a/packages/router/package.json b/packages/router/package.json deleted file mode 100644 index 68f6d00e32..0000000000 --- a/packages/router/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "@remix-run/router", - "version": "1.15.3", - "description": "Nested/Data-driven/Framework-agnostic Routing", - "keywords": [ - "remix", - "router", - "location" - ], - "repository": { - "type": "git", - "url": "https://github.com/remix-run/react-router", - "directory": "packages/router" - }, - "license": "MIT", - "author": "Remix Software ", - "sideEffects": false, - "main": "./dist/router.cjs.js", - "unpkg": "./dist/router.umd.min.js", - "module": "./dist/router.js", - "types": "./dist/index.d.ts", - "files": [ - "dist/", - "*.ts", - "CHANGELOG.md" - ], - "engines": { - "node": ">=14.0.0" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/packages/router/rollup.config.js b/packages/router/rollup.config.js deleted file mode 100644 index 78cf1c6858..0000000000 --- a/packages/router/rollup.config.js +++ /dev/null @@ -1,82 +0,0 @@ -const path = require("path"); - -const babel = require("@rollup/plugin-babel").default; -const typescript = require("@rollup/plugin-typescript"); -const copy = require("rollup-plugin-copy"); -const extensions = require("rollup-plugin-extensions"); -const prettier = require("rollup-plugin-prettier"); -const { terser } = require("rollup-plugin-terser"); - -const { - createBanner, - getBuildDirectories, - PRETTY, -} = require("../../rollup.utils"); -const { name, version } = require("./package.json"); - -function getRollupConfig( - format, - filename, - { includeTypesAndCopy, minify } = {} -) { - const { ROOT_DIR, SOURCE_DIR, OUTPUT_DIR } = getBuildDirectories( - name, - // We don't live in a folder matching our package name - "router" - ); - - return { - input: `${SOURCE_DIR}/index.ts`, - output: { - file: `${OUTPUT_DIR}/${filename}`, - format, - sourcemap: !PRETTY, - banner: createBanner("@remix-run/router", version), - ...(format === "umd" ? { name: "RemixRouter" } : {}), - }, - plugins: [ - extensions({ extensions: [".ts"] }), - babel({ - babelHelpers: "bundled", - exclude: /node_modules/, - presets: [ - ["@babel/preset-env", { loose: true }], - "@babel/preset-typescript", - ], - extensions: [".ts"], - }), - ...(includeTypesAndCopy === true - ? [ - typescript({ - tsconfig: path.join(__dirname, "tsconfig.json"), - exclude: ["__tests__"], - noEmitOnError: true, - }), - copy({ - targets: [ - { src: path.join(ROOT_DIR, "LICENSE.md"), dest: SOURCE_DIR }, - ], - verbose: true, - }), - ] - : []), - ...(minify === true ? [terser()] : []), - ].concat(PRETTY ? prettier({ parser: "babel" }) : []), - }; -} - -module.exports = function rollup() { - return [ - getRollupConfig("esm", "router.js", { includeTypesAndCopy: true }), - getRollupConfig("cjs", "router.cjs.js"), - getRollupConfig("umd", "router.umd.js"), - getRollupConfig("umd", "router.umd.min.js", { minify: true }), - ]; -}; - -/** - * @typedef {import('rollup').InputOptions} RollupInputOptions - * @typedef {import('rollup').OutputOptions} RollupOutputOptions - * @typedef {import('rollup').RollupOptions} RollupOptions - * @typedef {import('rollup').Plugin} RollupPlugin - */ diff --git a/packages/router/tsconfig.json b/packages/router/tsconfig.json deleted file mode 100644 index 72d956b941..0000000000 --- a/packages/router/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "include": ["index.ts"], - "exclude": ["dist/**/*"], - "compilerOptions": { - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "target": "ES2020", - "module": "ES2020", - "moduleResolution": "node", - - "strict": true, - - "declaration": true, - "emitDeclarationOnly": true, - - "skipLibCheck": true, - - "outDir": ".", - "rootDir": "." - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 97d73ab4bb..83f16ff76b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -233,10 +233,6 @@ importers: version: 3.1.1 packages/react-router: - dependencies: - '@remix-run/router': - specifier: workspace:* - version: link:../router devDependencies: react: specifier: ^18.2.0 @@ -247,9 +243,6 @@ importers: packages/react-router-dom: dependencies: - '@remix-run/router': - specifier: workspace:* - version: link:../router react-router: specifier: workspace:* version: link:../react-router @@ -263,9 +256,6 @@ importers: packages/react-router-dom-v5-compat: dependencies: - '@remix-run/router': - specifier: workspace:* - version: link:../router history: specifier: ^5.3.0 version: 5.3.0 @@ -307,8 +297,6 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) - packages/router: {} - packages: /@adobe/css-tools@4.2.0: diff --git a/scripts/publish.js b/scripts/publish.js index ee108fca46..652ec1949e 100644 --- a/scripts/publish.js +++ b/scripts/publish.js @@ -79,18 +79,12 @@ async function run() { console.log(` Publishing version ${version} to npm with tag "${tag}"`); // 3. Ensure build versions match the release version - if (version.includes("experimental")) { - // FIXME: @remix-run/router is versioned differently and is only handled - // for experimental releases here - await ensureBuildVersion("router", version); - } await ensureBuildVersion("react-router", version); await ensureBuildVersion("react-router-dom", version); await ensureBuildVersion("react-router-dom-v5-compat", version); await ensureBuildVersion("react-router-native", version); // 4. Publish to npm - publishBuild("router", tag); publishBuild("react-router", tag); publishBuild("react-router-dom", tag); publishBuild("react-router-dom-v5-compat", tag); diff --git a/scripts/version.js b/scripts/version.js index 30497c5c17..0caf6079af 100644 --- a/scripts/version.js +++ b/scripts/version.js @@ -59,16 +59,12 @@ async function run() { ensureCleanWorkingDirectory(); // 1. Get the next version number - let currentRouterVersion = await getPackageVersion("router"); let currentVersion = await getPackageVersion("react-router"); let version = semver.valid(givenVersion); if (version == null) { version = getNextVersion(currentVersion, givenVersion, prereleaseId); } - // We will only bump the router version if this is an experimental - let routerVersion = currentRouterVersion; - // 2. Confirm the next version number let answer = await prompt( `Are you sure you want to bump version ${currentVersion} to ${version}? [Yn] ` @@ -76,34 +72,15 @@ async function run() { if (answer === false) return 0; - // We only handle @remix-run/router for experimental since in normal/pre - // releases it's versioned independently from the rest of the packages - if (isExperimental) { - routerVersion = version; - // 2.5. Update @remix-run/router version - await updatePackageConfig("router", (config) => { - config.version = routerVersion; - }); - console.log( - chalk.green(` Updated @remix-run/router to version ${version}`) - ); - } - // 3. Update react-router version await updatePackageConfig("react-router", (config) => { config.version = version; - if (isExperimental) { - config.dependencies["@remix-run/router"] = routerVersion; - } }); console.log(chalk.green(` Updated react-router to version ${version}`)); // 4. Update react-router-dom version + react-router dep await updatePackageConfig("react-router-dom", (config) => { config.version = version; - if (isExperimental) { - config.dependencies["@remix-run/router"] = routerVersion; - } config.dependencies["react-router"] = version; }); console.log( @@ -135,9 +112,6 @@ async function run() { if (!stat.isDirectory()) continue; await updateExamplesPackageConfig(example, (config) => { - if (config.dependencies["@remix-run/router"]) { - config.dependencies["@remix-run/router"] = routerVersion; - } if (config.dependencies["react-router"]) { config.dependencies["react-router"] = version; }