From ba8d4fb62172576ad940c03bf816de2c84bb8a21 Mon Sep 17 00:00:00 2001 From: Matt Kindy <35696388+mattkindy@users.noreply.github.com> Date: Tue, 2 Jul 2024 08:50:38 -0500 Subject: [PATCH 01/30] Correct CSS docs example using links export in route file (#9685) --- contributors.yml | 1 + docs/guides/css-files.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/contributors.yml b/contributors.yml index fbfdbad94a3..f71419bc433 100644 --- a/contributors.yml +++ b/contributors.yml @@ -427,6 +427,7 @@ - MatthewAlbrecht - matthova - Mattinton +- mattkindy - mattmazzola - mattstobbs - maxprilutskiy diff --git a/docs/guides/css-files.md b/docs/guides/css-files.md index 323a3fcb01f..9b23bf07203 100644 --- a/docs/guides/css-files.md +++ b/docs/guides/css-files.md @@ -138,7 +138,7 @@ import { links as buttonLinks, } from "../components/Button"; -export const links = [...buttonLinks]; +export const links = () => [...buttonLinks]; export default function HelloRoute() { return ; From 35bd8f3639af0d3a5c5246b9f90e55595a4332c8 Mon Sep 17 00:00:00 2001 From: Muhammad Hadi <78081816+HadiMalikDev@users.noreply.github.com> Date: Wed, 3 Jul 2024 16:45:50 +0500 Subject: [PATCH 02/30] Update use-revalidator.md (#9694) --- contributors.yml | 1 + docs/hooks/use-revalidator.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/contributors.yml b/contributors.yml index f71419bc433..a9f38070bea 100644 --- a/contributors.yml +++ b/contributors.yml @@ -230,6 +230,7 @@ - gustavopch - gyx1000 - hadizz +- hadimalikdev - haines - hardingmatt - harmony7 diff --git a/docs/hooks/use-revalidator.md b/docs/hooks/use-revalidator.md index 9889ba16193..b78561b9f96 100644 --- a/docs/hooks/use-revalidator.md +++ b/docs/hooks/use-revalidator.md @@ -31,7 +31,7 @@ Remix already revalidates the data on the page automatically when actions are ca ### `revalidator.state` -The state the revalidation. Either `"idle"` or `"loading"`. +The state of the revalidation. Either `"idle"` or `"loading"`. ### `revalidator.revalidate()` From 4536ff56e52860476b703c41d06c905faa0558c7 Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Wed, 3 Jul 2024 11:47:04 +0000 Subject: [PATCH 03/30] chore: format --- contributors.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributors.yml b/contributors.yml index a9f38070bea..a1c32df2763 100644 --- a/contributors.yml +++ b/contributors.yml @@ -229,8 +229,8 @@ - gustavoguichard - gustavopch - gyx1000 -- hadizz - hadimalikdev +- hadizz - haines - hardingmatt - harmony7 From 4fd23dfc165a49a6348ecaca5ad5dad7e097f0b8 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 3 Jul 2024 10:31:47 -0400 Subject: [PATCH 04/30] Add note on FOW not hiding application routes --- docs/guides/fog-of-war.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/guides/fog-of-war.md b/docs/guides/fog-of-war.md index 054b36b892a..26b6df927c7 100644 --- a/docs/guides/fog-of-war.md +++ b/docs/guides/fog-of-war.md @@ -16,6 +16,8 @@ Currently, Remix loads the complete route manifest in a JS file on initial load When you enable "Fog of War", Remix will no longer send a full route manifest on initial load. Instead, your SSR render will only include the SSR routes in the initial manifest and additional routes will be loaded as the user navigates around the application. Over time, the manifest grows to include the portions of the app the user navigated to. +Please note that this is **not** a way to "hide" any of your application URLs from end-users. It doesn't ship them all in the manifest initially, but the manifest endpoint used to fetch new routes as the user navigates around will still have the ability to expose all of your defined application routes - albeit it's just a bit more obscured. + ### Eager Route Discovery As always, there is a tradeoff with this type of lazy-route discovery. It improves initial application load times -- but Remix can no longer perform synchronous route matching on link clicks, which can lead to waterfalls. From 2592089ca7bd461568b6d397859f3acb489dd690 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 3 Jul 2024 21:02:43 -0400 Subject: [PATCH 05/30] Enter prerelease mode --- .changeset/pre.json | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000000..50ac176c5c6 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,29 @@ +{ + "mode": "pre", + "tag": "pre", + "initialVersions": { + "integration": "0.0.0", + "integration-cf-template": "0.0.0", + "integration-deno-template": "0.0.0", + "integration-node-template": "0.0.0", + "integration-vite-cloudflare-template": "0.0.0", + "integration-vite-template": "0.0.0", + "create-remix": "2.10.1", + "remix": "2.10.1", + "@remix-run/architect": "2.10.1", + "@remix-run/cloudflare": "2.10.1", + "@remix-run/cloudflare-pages": "2.10.1", + "@remix-run/cloudflare-workers": "2.10.1", + "@remix-run/css-bundle": "2.10.1", + "@remix-run/deno": "2.10.1", + "@remix-run/dev": "2.10.1", + "@remix-run/eslint-config": "2.10.1", + "@remix-run/express": "2.10.1", + "@remix-run/node": "2.10.1", + "@remix-run/react": "2.10.1", + "@remix-run/serve": "2.10.1", + "@remix-run/server-runtime": "2.10.1", + "@remix-run/testing": "2.10.1" + }, + "changesets": [] +} From 36d60f90203c2d4563ce58947b0f0041e8d1b43e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Jul 2024 21:04:58 -0400 Subject: [PATCH 06/30] chore: Update version for release (pre) (#9707) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 5 ++++- .../helpers/vite-cloudflare-template/package.json | 6 +++--- packages/create-remix/CHANGELOG.md | 2 ++ packages/create-remix/package.json | 2 +- packages/remix-architect/CHANGELOG.md | 7 +++++++ packages/remix-architect/package.json | 2 +- packages/remix-cloudflare-pages/CHANGELOG.md | 7 +++++++ packages/remix-cloudflare-pages/package.json | 2 +- packages/remix-cloudflare-workers/CHANGELOG.md | 7 +++++++ packages/remix-cloudflare-workers/package.json | 2 +- packages/remix-cloudflare/CHANGELOG.md | 7 +++++++ packages/remix-cloudflare/package.json | 2 +- packages/remix-css-bundle/CHANGELOG.md | 2 ++ packages/remix-css-bundle/package.json | 2 +- packages/remix-deno/CHANGELOG.md | 7 +++++++ packages/remix-deno/package.json | 2 +- packages/remix-dev/CHANGELOG.md | 10 ++++++++++ packages/remix-dev/package.json | 6 +++--- packages/remix-eslint-config/CHANGELOG.md | 2 ++ packages/remix-eslint-config/package.json | 2 +- packages/remix-express/CHANGELOG.md | 7 +++++++ packages/remix-express/package.json | 2 +- packages/remix-node/CHANGELOG.md | 7 +++++++ packages/remix-node/package.json | 2 +- packages/remix-react/CHANGELOG.md | 8 ++++++++ packages/remix-react/package.json | 2 +- packages/remix-serve/CHANGELOG.md | 8 ++++++++ packages/remix-serve/package.json | 2 +- packages/remix-server-runtime/CHANGELOG.md | 6 ++++++ packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/CHANGELOG.md | 8 ++++++++ packages/remix-testing/package.json | 2 +- packages/remix/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 34 files changed, 124 insertions(+), 26 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 50ac176c5c6..1e83166ab00 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -25,5 +25,8 @@ "@remix-run/server-runtime": "2.10.1", "@remix-run/testing": "2.10.1" }, - "changesets": [] + "changesets": [ + "cyan-dingos-report", + "young-hairs-hug" + ] } diff --git a/integration/helpers/vite-cloudflare-template/package.json b/integration/helpers/vite-cloudflare-template/package.json index adf3e44dc3f..e3f88c0443c 100644 --- a/integration/helpers/vite-cloudflare-template/package.json +++ b/integration/helpers/vite-cloudflare-template/package.json @@ -11,9 +11,9 @@ "typecheck": "tsc" }, "dependencies": { - "@remix-run/cloudflare": "2.10.1", - "@remix-run/cloudflare-pages": "2.10.1", - "@remix-run/react": "2.10.1", + "@remix-run/cloudflare": "2.10.2-pre.0", + "@remix-run/cloudflare-pages": "2.10.2-pre.0", + "@remix-run/react": "2.10.2-pre.0", "isbot": "^4.1.0", "miniflare": "^3.20231030.4", "react": "^18.2.0", diff --git a/packages/create-remix/CHANGELOG.md b/packages/create-remix/CHANGELOG.md index 3eed379d429..364067b3ae1 100644 --- a/packages/create-remix/CHANGELOG.md +++ b/packages/create-remix/CHANGELOG.md @@ -1,5 +1,7 @@ # `create-remix` +## 2.10.2-pre.0 + ## 2.10.1 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.1. diff --git a/packages/create-remix/package.json b/packages/create-remix/package.json index 11e24455855..407a232079a 100644 --- a/packages/create-remix/package.json +++ b/packages/create-remix/package.json @@ -1,6 +1,6 @@ { "name": "create-remix", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Create a new Remix app", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-architect/CHANGELOG.md b/packages/remix-architect/CHANGELOG.md index d6930979f1b..3b872b98817 100644 --- a/packages/remix-architect/CHANGELOG.md +++ b/packages/remix-architect/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/architect` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-architect/package.json b/packages/remix-architect/package.json index 5bf7cc083d7..790c2082118 100644 --- a/packages/remix-architect/package.json +++ b/packages/remix-architect/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/architect", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Architect server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-pages/CHANGELOG.md b/packages/remix-cloudflare-pages/CHANGELOG.md index a52fc3bedf9..b03f15e084f 100644 --- a/packages/remix-cloudflare-pages/CHANGELOG.md +++ b/packages/remix-cloudflare-pages/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare-pages` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/cloudflare@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-cloudflare-pages/package.json b/packages/remix-cloudflare-pages/package.json index 5df08186148..be8205b495b 100644 --- a/packages/remix-cloudflare-pages/package.json +++ b/packages/remix-cloudflare-pages/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-pages", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Cloudflare Pages request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-workers/CHANGELOG.md b/packages/remix-cloudflare-workers/CHANGELOG.md index 9d6a0ed9110..7d4c749a105 100644 --- a/packages/remix-cloudflare-workers/CHANGELOG.md +++ b/packages/remix-cloudflare-workers/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare-workers` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/cloudflare@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-cloudflare-workers/package.json b/packages/remix-cloudflare-workers/package.json index b1572cc0f3d..94557f412dc 100644 --- a/packages/remix-cloudflare-workers/package.json +++ b/packages/remix-cloudflare-workers/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-workers", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Cloudflare worker request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare/CHANGELOG.md b/packages/remix-cloudflare/CHANGELOG.md index f36eba32bf4..3bc1f04b7b2 100644 --- a/packages/remix-cloudflare/CHANGELOG.md +++ b/packages/remix-cloudflare/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-cloudflare/package.json b/packages/remix-cloudflare/package.json index 7ce04a1417e..580154d0b67 100644 --- a/packages/remix-cloudflare/package.json +++ b/packages/remix-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Cloudflare platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-css-bundle/CHANGELOG.md b/packages/remix-css-bundle/CHANGELOG.md index b3a32801c40..7c45d2956e2 100644 --- a/packages/remix-css-bundle/CHANGELOG.md +++ b/packages/remix-css-bundle/CHANGELOG.md @@ -1,5 +1,7 @@ # @remix-run/css-bundle +## 2.10.2-pre.0 + ## 2.10.1 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.1. diff --git a/packages/remix-css-bundle/package.json b/packages/remix-css-bundle/package.json index 1c34d45c018..a0cdbfffabf 100644 --- a/packages/remix-css-bundle/package.json +++ b/packages/remix-css-bundle/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/css-bundle", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "CSS bundle href when using CSS bundling features in Remix", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-deno/CHANGELOG.md b/packages/remix-deno/CHANGELOG.md index feeea8536db..137e435bc32 100644 --- a/packages/remix-deno/CHANGELOG.md +++ b/packages/remix-deno/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/deno` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-deno/package.json b/packages/remix-deno/package.json index 4367c231232..f1ab1178eb4 100644 --- a/packages/remix-deno/package.json +++ b/packages/remix-deno/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/deno", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Deno platform abstractions for Remix", "homepage": "https://remix.run", "main": "./index.ts", diff --git a/packages/remix-dev/CHANGELOG.md b/packages/remix-dev/CHANGELOG.md index f686ee22ab4..58c55237638 100644 --- a/packages/remix-dev/CHANGELOG.md +++ b/packages/remix-dev/CHANGELOG.md @@ -1,5 +1,15 @@ # `@remix-run/dev` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.2-pre.0` + - `@remix-run/react@2.10.2-pre.0` + - `@remix-run/node@2.10.2-pre.0` + - `@remix-run/serve@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 7fd62946163..b860642d0b3 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/dev", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Dev tools and CLI for Remix", "homepage": "https://remix.run", "bugs": { @@ -106,8 +106,8 @@ "wrangler": "^3.28.2" }, "peerDependencies": { - "@remix-run/react": "^2.10.1", - "@remix-run/serve": "^2.10.1", + "@remix-run/react": "^2.10.2-pre.0", + "@remix-run/serve": "^2.10.2-pre.0", "typescript": "^5.1.0", "vite": "^5.1.0", "wrangler": "^3.28.2" diff --git a/packages/remix-eslint-config/CHANGELOG.md b/packages/remix-eslint-config/CHANGELOG.md index 5b0d20a48b3..7b1c4bd7e14 100644 --- a/packages/remix-eslint-config/CHANGELOG.md +++ b/packages/remix-eslint-config/CHANGELOG.md @@ -1,5 +1,7 @@ # `@remix-run/eslint-config` +## 2.10.2-pre.0 + ## 2.10.1 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.1. diff --git a/packages/remix-eslint-config/package.json b/packages/remix-eslint-config/package.json index 19119e9ed5f..03240a81496 100644 --- a/packages/remix-eslint-config/package.json +++ b/packages/remix-eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/eslint-config", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "ESLint configuration for Remix projects", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-express/CHANGELOG.md b/packages/remix-express/CHANGELOG.md index 1b88f6bb05f..0bcd7aca079 100644 --- a/packages/remix-express/CHANGELOG.md +++ b/packages/remix-express/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/express` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-express/package.json b/packages/remix-express/package.json index 27a8b2b2a9a..355b9101a4e 100644 --- a/packages/remix-express/package.json +++ b/packages/remix-express/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/express", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Express server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-node/CHANGELOG.md b/packages/remix-node/CHANGELOG.md index bf7ecbef5b7..bc6d7a285df 100644 --- a/packages/remix-node/CHANGELOG.md +++ b/packages/remix-node/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/node` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-node/package.json b/packages/remix-node/package.json index 8fb954a9cfe..6f3f4c808b4 100644 --- a/packages/remix-node/package.json +++ b/packages/remix-node/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/node", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Node.js platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-react/CHANGELOG.md b/packages/remix-react/CHANGELOG.md index cc30bb28839..8f7e32bec42 100644 --- a/packages/remix-react/CHANGELOG.md +++ b/packages/remix-react/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/react` +## 2.10.2-pre.0 + +### Patch Changes + +- forward ref to Form ([`64be40070`](https://github.com/remix-run/remix/commit/64be40070883f866e85b1131afb10b092ffe6045)) +- Updated dependencies: + - `@remix-run/server-runtime@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 1052f90aa4d..62db80c90d7 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/react", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "React DOM bindings for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-serve/CHANGELOG.md b/packages/remix-serve/CHANGELOG.md index 54c7e827495..1868bc5a092 100644 --- a/packages/remix-serve/CHANGELOG.md +++ b/packages/remix-serve/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/serve` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.2-pre.0` + - `@remix-run/express@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-serve/package.json b/packages/remix-serve/package.json index bbbacfd6164..fdb94ddf094 100644 --- a/packages/remix-serve/package.json +++ b/packages/remix-serve/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/serve", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Production application server for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-server-runtime/CHANGELOG.md b/packages/remix-server-runtime/CHANGELOG.md index b460082fb6d..21363964b30 100644 --- a/packages/remix-server-runtime/CHANGELOG.md +++ b/packages/remix-server-runtime/CHANGELOG.md @@ -1,5 +1,11 @@ # `@remix-run/server-runtime` +## 2.10.2-pre.0 + +### Patch Changes + +- Fix issue with setting additional headers on raw native fetch responses with immutable headers ([#9693](https://github.com/remix-run/remix/pull/9693)) + ## 2.10.1 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.1. diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index a124a8ef151..708a3bac62b 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/server-runtime", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Server runtime for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-testing/CHANGELOG.md b/packages/remix-testing/CHANGELOG.md index a52bfd140b3..f1e3067f4a4 100644 --- a/packages/remix-testing/CHANGELOG.md +++ b/packages/remix-testing/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/testing` +## 2.10.2-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/react@2.10.2-pre.0` + - `@remix-run/node@2.10.2-pre.0` + ## 2.10.1 ### Patch Changes diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index ad481ad9d81..fbab6a80555 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix/package.json b/packages/remix/package.json index 69f97f3cb51..3c53c3baac3 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "remix", - "version": "2.10.1", + "version": "2.10.2-pre.0", "description": "A framework for building better websites", "homepage": "https://remix.run", "bugs": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2420dd9491c..0bf8df936cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,13 +548,13 @@ importers: integration/helpers/vite-cloudflare-template: dependencies: '@remix-run/cloudflare': - specifier: 2.10.1 + specifier: 2.10.2-pre.0 version: link:../../../packages/remix-cloudflare '@remix-run/cloudflare-pages': - specifier: 2.10.1 + specifier: 2.10.2-pre.0 version: link:../../../packages/remix-cloudflare-pages '@remix-run/react': - specifier: 2.10.1 + specifier: 2.10.2-pre.0 version: link:../../../packages/remix-react isbot: specifier: ^4.1.0 @@ -865,7 +865,7 @@ importers: specifier: workspace:* version: link:../remix-node '@remix-run/react': - specifier: ^2.10.1 + specifier: ^2.10.2-pre.0 version: link:../remix-react '@remix-run/router': specifier: 1.17.1 From 0fa701019af530866ea75b8219f11e03a08b238f Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 3 Jul 2024 21:10:12 -0400 Subject: [PATCH 07/30] Draft release notes --- .changeset/young-hairs-hug.md | 2 +- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/.changeset/young-hairs-hug.md b/.changeset/young-hairs-hug.md index 18c64c08de4..b1422604afe 100644 --- a/.changeset/young-hairs-hug.md +++ b/.changeset/young-hairs-hug.md @@ -2,4 +2,4 @@ "@remix-run/react": patch --- -forward ref to Form +Forward `ref` to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e033cb983c..722a0528bde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -187,6 +187,35 @@ Date: YYYY-MM-DD --> +## v2.10.2 + +Date: 2024-07-04 + +### Patch Changes + +- `@remix-run/react` - Forward ref to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) +- `@remix-run/server-runtime` - Fix issue setting additional headers on raw native `fetch` responses with immutable headers ([#9693](https://github.com/remix-run/remix/pull/9693)) + +### Changes by Package + +- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/create-remix/CHANGELOG.md#2102) +- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-architect/CHANGELOG.md#2102) +- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-cloudflare/CHANGELOG.md#2102) +- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-cloudflare-pages/CHANGELOG.md#2102) +- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-cloudflare-workers/CHANGELOG.md#2102) +- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-css-bundle/CHANGELOG.md#2102) +- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-deno/CHANGELOG.md#2102) +- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-dev/CHANGELOG.md#2102) +- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-eslint-config/CHANGELOG.md#2102) +- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-express/CHANGELOG.md#2102) +- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-node/CHANGELOG.md#2102) +- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-react/CHANGELOG.md#2102) +- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-serve/CHANGELOG.md#2102) +- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-server-runtime/CHANGELOG.md#2102) +- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.10.2/packages/remix-testing/CHANGELOG.md#2102) + +**Full Changelog**: [`v2.10.1...v2.10.2`](https://github.com/remix-run/remix/compare/remix@2.10.1...remix@2.10.2) + ## v2.10.1 Date: 2024-07-03 From 65b4a3c9af2f01b01ebf827b1737b14aadbccd8b Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 4 Jul 2024 08:13:08 -0400 Subject: [PATCH 08/30] Exit prerelease mode --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 1e83166ab00..63585f93ade 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "pre", "initialVersions": { "integration": "0.0.0", From d0aac53cd64cf7f02a0183986663305e26114d6a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 4 Jul 2024 09:19:09 -0400 Subject: [PATCH 09/30] chore: Update version for release (#9712) Co-authored-by: github-actions[bot] Co-authored-by: Matt Brophy --- .changeset/cyan-dingos-report.md | 5 --- .changeset/pre.json | 32 ------------------- .changeset/young-hairs-hug.md | 5 --- CHANGELOG.md | 4 +-- .../vite-cloudflare-template/package.json | 6 ++-- packages/create-remix/CHANGELOG.md | 4 ++- packages/create-remix/package.json | 2 +- packages/remix-architect/CHANGELOG.md | 4 +-- packages/remix-architect/package.json | 2 +- packages/remix-cloudflare-pages/CHANGELOG.md | 4 +-- packages/remix-cloudflare-pages/package.json | 2 +- .../remix-cloudflare-workers/CHANGELOG.md | 4 +-- .../remix-cloudflare-workers/package.json | 2 +- packages/remix-cloudflare/CHANGELOG.md | 4 +-- packages/remix-cloudflare/package.json | 2 +- packages/remix-css-bundle/CHANGELOG.md | 4 ++- packages/remix-css-bundle/package.json | 2 +- packages/remix-deno/CHANGELOG.md | 4 +-- packages/remix-deno/package.json | 2 +- packages/remix-dev/CHANGELOG.md | 8 ++--- packages/remix-dev/package.json | 6 ++-- packages/remix-eslint-config/CHANGELOG.md | 4 ++- packages/remix-eslint-config/package.json | 2 +- packages/remix-express/CHANGELOG.md | 4 +-- packages/remix-express/package.json | 2 +- packages/remix-node/CHANGELOG.md | 4 +-- packages/remix-node/package.json | 2 +- packages/remix-react/CHANGELOG.md | 6 ++-- packages/remix-react/package.json | 2 +- packages/remix-serve/CHANGELOG.md | 6 ++-- packages/remix-serve/package.json | 2 +- packages/remix-server-runtime/CHANGELOG.md | 4 +-- packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/CHANGELOG.md | 6 ++-- packages/remix-testing/package.json | 2 +- packages/remix/package.json | 2 +- pnpm-lock.yaml | 8 ++--- 37 files changed, 64 insertions(+), 102 deletions(-) delete mode 100644 .changeset/cyan-dingos-report.md delete mode 100644 .changeset/pre.json delete mode 100644 .changeset/young-hairs-hug.md diff --git a/.changeset/cyan-dingos-report.md b/.changeset/cyan-dingos-report.md deleted file mode 100644 index 0a9b7616faf..00000000000 --- a/.changeset/cyan-dingos-report.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/server-runtime": patch ---- - -Fix issue with setting additional headers on raw native fetch responses with immutable headers diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 63585f93ade..00000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "mode": "exit", - "tag": "pre", - "initialVersions": { - "integration": "0.0.0", - "integration-cf-template": "0.0.0", - "integration-deno-template": "0.0.0", - "integration-node-template": "0.0.0", - "integration-vite-cloudflare-template": "0.0.0", - "integration-vite-template": "0.0.0", - "create-remix": "2.10.1", - "remix": "2.10.1", - "@remix-run/architect": "2.10.1", - "@remix-run/cloudflare": "2.10.1", - "@remix-run/cloudflare-pages": "2.10.1", - "@remix-run/cloudflare-workers": "2.10.1", - "@remix-run/css-bundle": "2.10.1", - "@remix-run/deno": "2.10.1", - "@remix-run/dev": "2.10.1", - "@remix-run/eslint-config": "2.10.1", - "@remix-run/express": "2.10.1", - "@remix-run/node": "2.10.1", - "@remix-run/react": "2.10.1", - "@remix-run/serve": "2.10.1", - "@remix-run/server-runtime": "2.10.1", - "@remix-run/testing": "2.10.1" - }, - "changesets": [ - "cyan-dingos-report", - "young-hairs-hug" - ] -} diff --git a/.changeset/young-hairs-hug.md b/.changeset/young-hairs-hug.md deleted file mode 100644 index b1422604afe..00000000000 --- a/.changeset/young-hairs-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/react": patch ---- - -Forward `ref` to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) diff --git a/CHANGELOG.md b/CHANGELOG.md index 722a0528bde..167e0eb90f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -193,8 +193,8 @@ Date: 2024-07-04 ### Patch Changes -- `@remix-run/react` - Forward ref to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) -- `@remix-run/server-runtime` - Fix issue setting additional headers on raw native `fetch` responses with immutable headers ([#9693](https://github.com/remix-run/remix/pull/9693)) +- `@remix-run/react` - Forward `ref` to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) +- `@remix-run/server-runtime` - Fix bug with `immutable` headers on raw native `fetch` responses returned from loaders ([#9693](https://github.com/remix-run/remix/pull/9693)) ### Changes by Package diff --git a/integration/helpers/vite-cloudflare-template/package.json b/integration/helpers/vite-cloudflare-template/package.json index e3f88c0443c..f01a4bcbf3a 100644 --- a/integration/helpers/vite-cloudflare-template/package.json +++ b/integration/helpers/vite-cloudflare-template/package.json @@ -11,9 +11,9 @@ "typecheck": "tsc" }, "dependencies": { - "@remix-run/cloudflare": "2.10.2-pre.0", - "@remix-run/cloudflare-pages": "2.10.2-pre.0", - "@remix-run/react": "2.10.2-pre.0", + "@remix-run/cloudflare": "2.10.2", + "@remix-run/cloudflare-pages": "2.10.2", + "@remix-run/react": "2.10.2", "isbot": "^4.1.0", "miniflare": "^3.20231030.4", "react": "^18.2.0", diff --git a/packages/create-remix/CHANGELOG.md b/packages/create-remix/CHANGELOG.md index 364067b3ae1..63172c8485a 100644 --- a/packages/create-remix/CHANGELOG.md +++ b/packages/create-remix/CHANGELOG.md @@ -1,6 +1,8 @@ # `create-remix` -## 2.10.2-pre.0 +## 2.10.2 + +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.2. ## 2.10.1 diff --git a/packages/create-remix/package.json b/packages/create-remix/package.json index 407a232079a..9fae83053d5 100644 --- a/packages/create-remix/package.json +++ b/packages/create-remix/package.json @@ -1,6 +1,6 @@ { "name": "create-remix", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Create a new Remix app", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-architect/CHANGELOG.md b/packages/remix-architect/CHANGELOG.md index 3b872b98817..5a5b8252609 100644 --- a/packages/remix-architect/CHANGELOG.md +++ b/packages/remix-architect/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/architect` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/node@2.10.2-pre.0` + - `@remix-run/node@2.10.2` ## 2.10.1 diff --git a/packages/remix-architect/package.json b/packages/remix-architect/package.json index 790c2082118..e008402bcdd 100644 --- a/packages/remix-architect/package.json +++ b/packages/remix-architect/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/architect", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Architect server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-pages/CHANGELOG.md b/packages/remix-cloudflare-pages/CHANGELOG.md index b03f15e084f..8ac550bfd16 100644 --- a/packages/remix-cloudflare-pages/CHANGELOG.md +++ b/packages/remix-cloudflare-pages/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/cloudflare-pages` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/cloudflare@2.10.2-pre.0` + - `@remix-run/cloudflare@2.10.2` ## 2.10.1 diff --git a/packages/remix-cloudflare-pages/package.json b/packages/remix-cloudflare-pages/package.json index be8205b495b..ab1d6b14ea1 100644 --- a/packages/remix-cloudflare-pages/package.json +++ b/packages/remix-cloudflare-pages/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-pages", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Cloudflare Pages request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-workers/CHANGELOG.md b/packages/remix-cloudflare-workers/CHANGELOG.md index 7d4c749a105..c4d25388c51 100644 --- a/packages/remix-cloudflare-workers/CHANGELOG.md +++ b/packages/remix-cloudflare-workers/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/cloudflare-workers` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/cloudflare@2.10.2-pre.0` + - `@remix-run/cloudflare@2.10.2` ## 2.10.1 diff --git a/packages/remix-cloudflare-workers/package.json b/packages/remix-cloudflare-workers/package.json index 94557f412dc..76fe9c8b112 100644 --- a/packages/remix-cloudflare-workers/package.json +++ b/packages/remix-cloudflare-workers/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-workers", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Cloudflare worker request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare/CHANGELOG.md b/packages/remix-cloudflare/CHANGELOG.md index 3bc1f04b7b2..fe9bf555395 100644 --- a/packages/remix-cloudflare/CHANGELOG.md +++ b/packages/remix-cloudflare/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/cloudflare` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.2-pre.0` + - `@remix-run/server-runtime@2.10.2` ## 2.10.1 diff --git a/packages/remix-cloudflare/package.json b/packages/remix-cloudflare/package.json index 580154d0b67..d5566b9aa49 100644 --- a/packages/remix-cloudflare/package.json +++ b/packages/remix-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Cloudflare platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-css-bundle/CHANGELOG.md b/packages/remix-css-bundle/CHANGELOG.md index 7c45d2956e2..d266a0d960a 100644 --- a/packages/remix-css-bundle/CHANGELOG.md +++ b/packages/remix-css-bundle/CHANGELOG.md @@ -1,6 +1,8 @@ # @remix-run/css-bundle -## 2.10.2-pre.0 +## 2.10.2 + +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.2. ## 2.10.1 diff --git a/packages/remix-css-bundle/package.json b/packages/remix-css-bundle/package.json index a0cdbfffabf..11a31b7ea09 100644 --- a/packages/remix-css-bundle/package.json +++ b/packages/remix-css-bundle/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/css-bundle", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "CSS bundle href when using CSS bundling features in Remix", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-deno/CHANGELOG.md b/packages/remix-deno/CHANGELOG.md index 137e435bc32..cc3670f0599 100644 --- a/packages/remix-deno/CHANGELOG.md +++ b/packages/remix-deno/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/deno` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.2-pre.0` + - `@remix-run/server-runtime@2.10.2` ## 2.10.1 diff --git a/packages/remix-deno/package.json b/packages/remix-deno/package.json index f1ab1178eb4..73c7cf21e94 100644 --- a/packages/remix-deno/package.json +++ b/packages/remix-deno/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/deno", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Deno platform abstractions for Remix", "homepage": "https://remix.run", "main": "./index.ts", diff --git a/packages/remix-dev/CHANGELOG.md b/packages/remix-dev/CHANGELOG.md index 58c55237638..c1513d2b490 100644 --- a/packages/remix-dev/CHANGELOG.md +++ b/packages/remix-dev/CHANGELOG.md @@ -1,14 +1,12 @@ # `@remix-run/dev` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.2-pre.0` - - `@remix-run/react@2.10.2-pre.0` - - `@remix-run/node@2.10.2-pre.0` - - `@remix-run/serve@2.10.2-pre.0` + - `@remix-run/server-runtime@2.10.2` + - `@remix-run/node@2.10.2` ## 2.10.1 diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index b860642d0b3..8384871652b 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/dev", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Dev tools and CLI for Remix", "homepage": "https://remix.run", "bugs": { @@ -106,8 +106,8 @@ "wrangler": "^3.28.2" }, "peerDependencies": { - "@remix-run/react": "^2.10.2-pre.0", - "@remix-run/serve": "^2.10.2-pre.0", + "@remix-run/react": "^2.10.2", + "@remix-run/serve": "^2.10.2", "typescript": "^5.1.0", "vite": "^5.1.0", "wrangler": "^3.28.2" diff --git a/packages/remix-eslint-config/CHANGELOG.md b/packages/remix-eslint-config/CHANGELOG.md index 7b1c4bd7e14..d4f72bbdc88 100644 --- a/packages/remix-eslint-config/CHANGELOG.md +++ b/packages/remix-eslint-config/CHANGELOG.md @@ -1,6 +1,8 @@ # `@remix-run/eslint-config` -## 2.10.2-pre.0 +## 2.10.2 + +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.2. ## 2.10.1 diff --git a/packages/remix-eslint-config/package.json b/packages/remix-eslint-config/package.json index 03240a81496..007b4bf94f6 100644 --- a/packages/remix-eslint-config/package.json +++ b/packages/remix-eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/eslint-config", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "ESLint configuration for Remix projects", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-express/CHANGELOG.md b/packages/remix-express/CHANGELOG.md index 0bcd7aca079..ab94fb4df49 100644 --- a/packages/remix-express/CHANGELOG.md +++ b/packages/remix-express/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/express` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/node@2.10.2-pre.0` + - `@remix-run/node@2.10.2` ## 2.10.1 diff --git a/packages/remix-express/package.json b/packages/remix-express/package.json index 355b9101a4e..85692db41ae 100644 --- a/packages/remix-express/package.json +++ b/packages/remix-express/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/express", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Express server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-node/CHANGELOG.md b/packages/remix-node/CHANGELOG.md index bc6d7a285df..1de9ef0a36e 100644 --- a/packages/remix-node/CHANGELOG.md +++ b/packages/remix-node/CHANGELOG.md @@ -1,11 +1,11 @@ # `@remix-run/node` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.2-pre.0` + - `@remix-run/server-runtime@2.10.2` ## 2.10.1 diff --git a/packages/remix-node/package.json b/packages/remix-node/package.json index 6f3f4c808b4..be2241f0522 100644 --- a/packages/remix-node/package.json +++ b/packages/remix-node/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/node", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Node.js platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-react/CHANGELOG.md b/packages/remix-react/CHANGELOG.md index 8f7e32bec42..a1075384620 100644 --- a/packages/remix-react/CHANGELOG.md +++ b/packages/remix-react/CHANGELOG.md @@ -1,12 +1,12 @@ # `@remix-run/react` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes -- forward ref to Form ([`64be40070`](https://github.com/remix-run/remix/commit/64be40070883f866e85b1131afb10b092ffe6045)) +- Forward `ref` to `Form` ([`bdd04217`](https://github.com/remix-run/remix/commit/bdd04217713292307078a30dab9033926d48ede6)) - Updated dependencies: - - `@remix-run/server-runtime@2.10.2-pre.0` + - `@remix-run/server-runtime@2.10.2` ## 2.10.1 diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 62db80c90d7..5bb9e5feff9 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/react", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "React DOM bindings for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-serve/CHANGELOG.md b/packages/remix-serve/CHANGELOG.md index 1868bc5a092..d596e54fed7 100644 --- a/packages/remix-serve/CHANGELOG.md +++ b/packages/remix-serve/CHANGELOG.md @@ -1,12 +1,12 @@ # `@remix-run/serve` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/node@2.10.2-pre.0` - - `@remix-run/express@2.10.2-pre.0` + - `@remix-run/node@2.10.2` + - `@remix-run/express@2.10.2` ## 2.10.1 diff --git a/packages/remix-serve/package.json b/packages/remix-serve/package.json index fdb94ddf094..9b7d5866e22 100644 --- a/packages/remix-serve/package.json +++ b/packages/remix-serve/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/serve", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Production application server for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-server-runtime/CHANGELOG.md b/packages/remix-server-runtime/CHANGELOG.md index 21363964b30..3acc0c9a40c 100644 --- a/packages/remix-server-runtime/CHANGELOG.md +++ b/packages/remix-server-runtime/CHANGELOG.md @@ -1,10 +1,10 @@ # `@remix-run/server-runtime` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes -- Fix issue with setting additional headers on raw native fetch responses with immutable headers ([#9693](https://github.com/remix-run/remix/pull/9693)) +- Fix bug with `immutable` headers on raw native `fetch` responses returned from loaders ([#9693](https://github.com/remix-run/remix/pull/9693)) ## 2.10.1 diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 708a3bac62b..43a9db5cc0f 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/server-runtime", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Server runtime for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-testing/CHANGELOG.md b/packages/remix-testing/CHANGELOG.md index f1e3067f4a4..c8fe037ce3c 100644 --- a/packages/remix-testing/CHANGELOG.md +++ b/packages/remix-testing/CHANGELOG.md @@ -1,12 +1,12 @@ # `@remix-run/testing` -## 2.10.2-pre.0 +## 2.10.2 ### Patch Changes - Updated dependencies: - - `@remix-run/react@2.10.2-pre.0` - - `@remix-run/node@2.10.2-pre.0` + - `@remix-run/react@2.10.2` + - `@remix-run/node@2.10.2` ## 2.10.1 diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index fbab6a80555..6cc7347858b 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix/package.json b/packages/remix/package.json index 3c53c3baac3..d7ca9f846df 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "remix", - "version": "2.10.2-pre.0", + "version": "2.10.2", "description": "A framework for building better websites", "homepage": "https://remix.run", "bugs": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bf8df936cd..e62b78bd283 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,13 +548,13 @@ importers: integration/helpers/vite-cloudflare-template: dependencies: '@remix-run/cloudflare': - specifier: 2.10.2-pre.0 + specifier: 2.10.2 version: link:../../../packages/remix-cloudflare '@remix-run/cloudflare-pages': - specifier: 2.10.2-pre.0 + specifier: 2.10.2 version: link:../../../packages/remix-cloudflare-pages '@remix-run/react': - specifier: 2.10.2-pre.0 + specifier: 2.10.2 version: link:../../../packages/remix-react isbot: specifier: ^4.1.0 @@ -865,7 +865,7 @@ importers: specifier: workspace:* version: link:../remix-node '@remix-run/react': - specifier: ^2.10.2-pre.0 + specifier: ^2.10.2 version: link:../remix-react '@remix-run/router': specifier: 1.17.1 From bbead33bf530be030d16a1466b52cd99d077382a Mon Sep 17 00:00:00 2001 From: Andrew Patton Date: Wed, 10 Jul 2024 08:11:40 -0700 Subject: [PATCH 10/30] =?UTF-8?q?Properly=20bind=20cloudflare=20workers?= =?UTF-8?q?=E2=80=99=20ctx.waitUntil=20and=20ctx.passThroughOnException=20?= =?UTF-8?q?(#9696)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contributors.yml | 1 + templates/cloudflare-workers/server.js | 12 ++++-------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/contributors.yml b/contributors.yml index a1c32df2763..941193224a9 100644 --- a/contributors.yml +++ b/contributors.yml @@ -5,6 +5,7 @@ - abotsi - accidentaldeveloper - achinchen +- acusti - adamwathan - adicuco - AdiRishi diff --git a/templates/cloudflare-workers/server.js b/templates/cloudflare-workers/server.js index dfcfb3f5184..034653d326a 100644 --- a/templates/cloudflare-workers/server.js +++ b/templates/cloudflare-workers/server.js @@ -9,16 +9,15 @@ const handleRemixRequest = createRequestHandler(remixBuild); export default { async fetch(request, env, ctx) { + const waitUntil = ctx.waitUntil.bind(ctx); + const passThroughOnException = ctx.passThroughOnException.bind(ctx); try { const url = new URL(request.url); const ttl = url.pathname.startsWith("/assets/") ? 60 * 60 * 24 * 365 // 1 year : 60 * 5; // 5 minutes return await getAssetFromKV( - { - request, - waitUntil: ctx.waitUntil.bind(ctx), - }, + { request, waitUntil }, { ASSET_NAMESPACE: env.__STATIC_CONTENT, ASSET_MANIFEST: MANIFEST, @@ -40,10 +39,7 @@ export default { // `cloudflareDevProxyVitePlugin`: // https://developers.cloudflare.com/workers/wrangler/api/#getplatformproxy cf: request.cf, - ctx: { - waitUntil: ctx.waitUntil, - passThroughOnException: ctx.passThroughOnException, - }, + ctx: { waitUntil, passThroughOnException }, caches, env, }, From d58d4fbccde1d642dd37da9f306ca26792457e5b Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 10 Jul 2024 16:38:18 -0400 Subject: [PATCH 11/30] Single Fetch: proxy request signal through on interrupted loader calls (#9738) --- .changeset/fluffy-ways-bathe.md | 5 +++++ packages/remix-react/single-fetch.tsx | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 .changeset/fluffy-ways-bathe.md diff --git a/.changeset/fluffy-ways-bathe.md b/.changeset/fluffy-ways-bathe.md new file mode 100644 index 00000000000..16cbe962953 --- /dev/null +++ b/.changeset/fluffy-ways-bathe.md @@ -0,0 +1,5 @@ +--- +"@remix-run/react": patch +--- + +Single Fetch: Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation diff --git a/packages/remix-react/single-fetch.tsx b/packages/remix-react/single-fetch.tsx index 880ce796b87..1543dab05cf 100644 --- a/packages/remix-react/single-fetch.tsx +++ b/packages/remix-react/single-fetch.tsx @@ -192,12 +192,13 @@ function singleFetchLoaderStrategy( m.resolve(async (handler): Promise => { let result: unknown; let url = stripIndexParam(singleFetchUrl(request.url)); + let init = await createRequestInit(request); // When a route has a client loader, it calls it's singular server loader if (manifest.routes[m.route.id].hasClientLoader) { result = await handler(async () => { url.searchParams.set("_routes", m.route.id); - let { data } = await fetchAndDecode(url); + let { data } = await fetchAndDecode(url, init); return unwrapSingleFetchResults( data as SingleFetchResults, m.route.id @@ -214,7 +215,7 @@ function singleFetchLoaderStrategy( matches.filter((m) => m.shouldLoad).map((m) => m.route), url ); - singleFetchPromise = fetchAndDecode(url).then( + singleFetchPromise = fetchAndDecode(url, init).then( ({ data }) => data as SingleFetchResults ); } @@ -307,7 +308,7 @@ export function singleFetchUrl(reqUrl: URL | string) { return url; } -async function fetchAndDecode(url: URL, init?: RequestInit) { +async function fetchAndDecode(url: URL, init: RequestInit) { let res = await fetch(url, init); // Don't do a hard check against the header here. We'll get `text/x-turbo` // when we have a running server, but if folks want to prerender `.data` files From 01b868f52cb27acb4a4b7f97dd25a483ea0d7ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Comeau?= <114004123+sebastien-comeau@users.noreply.github.com> Date: Fri, 12 Jul 2024 11:33:16 -0300 Subject: [PATCH 12/30] docs: add info on FormData submitter and SubmitEvent compatibility (#9739) --- contributors.yml | 1 + docs/guides/faq.md | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/contributors.yml b/contributors.yml index 941193224a9..b699a984905 100644 --- a/contributors.yml +++ b/contributors.yml @@ -575,6 +575,7 @@ - sean-roberts - SeanGroff - SeanRoberts +- sebastien-comeau - sebz - selfish - sergiocarneiro diff --git a/docs/guides/faq.md b/docs/guides/faq.md index 021b411e9b0..333b67217b2 100644 --- a/docs/guides/faq.md +++ b/docs/guides/faq.md @@ -135,6 +135,8 @@ export default function Projects() { } ``` +Older browser versions might break this functionality because they might not support the [SubmitEvent: submitter property][submitevent-submitter] or the [FormData() constructor submitter parameter][formdata-submitter]. Be sure to check the browser compatibility for these features. If you need to polyfill this, please refer to the [Event Submitter Polyfill][polyfill-event-submitter] and the [FormData Submitter Polyfill][polyfill-formdata-submitter]. For more details, see the related issue [remix-run/remix#9704][remix-submitter-issue]. + ## How can I have structured data in a form? If you're used to doing fetches with a content type of `application/json`, you may wonder how forms fit into this. [`FormData`][form_data] is a bit different from JSON. @@ -233,3 +235,8 @@ Again, `formData.getAll()` is often all you need, we encourage you to give it a [query_string]: https://npm.im/query-string [ramda]: https://npm.im/ramda [watch_on_youtube]: https://www.youtube.com/watch?v=w2i-9cYxSdc&ab_channel=Remix +[submitevent-submitter]: https://developer.mozilla.org/en-US/docs/Web/API/SubmitEvent/submitter +[formdata-submitter]: https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData#submitter +[polyfill-event-submitter]: https://github.com/idea2app/event-submitter-polyfill +[polyfill-formdata-submitter]: https://github.com/jenseng/formdata-submitter-polyfill +[remix-submitter-issue]: https://github.com/remix-run/remix/issues/9704 From cb4dda07904030235896e95871006f9f980027ac Mon Sep 17 00:00:00 2001 From: Courey Elliott Date: Fri, 12 Jul 2024 11:20:03 -0400 Subject: [PATCH 13/30] reverting createRemixHeaders to previous fix for handling multiple cookies (#9664) Co-authored-by: Matt Brophy --- .changeset/few-planets-attend.md | 5 +++++ contributors.yml | 1 + packages/remix-architect/__tests__/server-test.ts | 13 +++++++++++++ packages/remix-architect/package.json | 1 + packages/remix-architect/server.ts | 14 +++++++++----- pnpm-lock.yaml | 3 +++ 6 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 .changeset/few-planets-attend.md diff --git a/.changeset/few-planets-attend.md b/.changeset/few-planets-attend.md new file mode 100644 index 00000000000..1777c4cd74f --- /dev/null +++ b/.changeset/few-planets-attend.md @@ -0,0 +1,5 @@ +--- +"@remix-run/architect": patch +--- + +Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation. diff --git a/contributors.yml b/contributors.yml index a1c32df2763..9317d74d7ce 100644 --- a/contributors.yml +++ b/contributors.yml @@ -114,6 +114,7 @@ - colinhacks - confix - coryhouse +- courey - courtyenn - craigayre - craigglennie diff --git a/packages/remix-architect/__tests__/server-test.ts b/packages/remix-architect/__tests__/server-test.ts index 196f00f9488..243ff5ad99c 100644 --- a/packages/remix-architect/__tests__/server-test.ts +++ b/packages/remix-architect/__tests__/server-test.ts @@ -1,6 +1,7 @@ import fsp from "node:fs/promises"; import path from "node:path"; import { createRequestHandler as createRemixRequestHandler } from "@remix-run/node"; +import { Headers as RemixHeaders } from "@remix-run/web-fetch"; import type { APIGatewayProxyEventV2 } from "aws-lambda"; import lambdaTester from "lambda-tester"; @@ -230,6 +231,18 @@ describe("architect createRemixHeaders", () => { "__session=some_value; __other=some_other_value" ); }); + + it("handles multiple request cookies when using @remix-run/web-fetch", () => { + let headers = createRemixHeaders( + {}, + ["__session=some_value", "__other=some_other_value"], + // @ts-expect-error types don't align since it's not fully spec compliant + RemixHeaders + ); + expect(headers.get("cookie")).toEqual( + "__session=some_value; __other=some_other_value" + ); + }); }); }); diff --git a/packages/remix-architect/package.json b/packages/remix-architect/package.json index e008402bcdd..dcfdffaf0b1 100644 --- a/packages/remix-architect/package.json +++ b/packages/remix-architect/package.json @@ -19,6 +19,7 @@ "dependencies": { "@architect/functions": "^5.2.0", "@remix-run/node": "workspace:*", + "@remix-run/web-fetch": "^4.4.2", "@types/aws-lambda": "^8.10.82" }, "devDependencies": { diff --git a/packages/remix-architect/server.ts b/packages/remix-architect/server.ts index 6ad6c1c692b..52fa5a0bcd3 100644 --- a/packages/remix-architect/server.ts +++ b/packages/remix-architect/server.ts @@ -77,9 +77,15 @@ export function createRemixRequest(event: APIGatewayProxyEventV2): Request { export function createRemixHeaders( requestHeaders: APIGatewayProxyEventHeaders, - requestCookies?: string[] + requestCookies?: string[], + _Headers?: typeof Headers ): Headers { - let headers = new Headers(); + // `_Headers` should only be used for unit testing purposes so we can unit test + // the different behaviors of the @remix-run/web-fetch `Headers` implementation + // and the node/undici implementation. See: + // https://github.com/remix-run/remix/issues/9657 + let HeadersImpl = _Headers || Headers; + let headers = new HeadersImpl(); for (let [header, value] of Object.entries(requestHeaders)) { if (value) { @@ -88,9 +94,7 @@ export function createRemixHeaders( } if (requestCookies) { - for (let cookie of requestCookies) { - headers.append("Cookie", cookie); - } + headers.append("Cookie", requestCookies.join("; ")); } return headers; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e62b78bd283..65b97bab3a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -744,6 +744,9 @@ importers: '@remix-run/node': specifier: workspace:* version: link:../remix-node + '@remix-run/web-fetch': + specifier: ^4.4.2 + version: 4.4.2 '@types/aws-lambda': specifier: ^8.10.82 version: 8.10.133 From 5bccd1e7586fc336ecff97a631e977fefd6bd185 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 12 Jul 2024 11:45:59 -0400 Subject: [PATCH 14/30] Log route module errors prior to reloading the page (#8932) --- .changeset/log-module-error.md | 5 +++++ packages/remix-react/routeModules.ts | 22 +++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 .changeset/log-module-error.md diff --git a/.changeset/log-module-error.md b/.changeset/log-module-error.md new file mode 100644 index 00000000000..5db9a136451 --- /dev/null +++ b/.changeset/log-module-error.md @@ -0,0 +1,5 @@ +--- +"@remix-run/react": patch +--- + +Log any errors encountered loading a route module prior to reloading the page diff --git a/packages/remix-react/routeModules.ts b/packages/remix-react/routeModules.ts index 7c37854e32d..0867e6ff07f 100644 --- a/packages/remix-react/routeModules.ts +++ b/packages/remix-react/routeModules.ts @@ -190,10 +190,21 @@ export async function loadRouteModule( routeModulesCache[route.id] = routeModule; return routeModule; } catch (error: unknown) { - // User got caught in the middle of a deploy and the CDN no longer has the - // asset we're trying to import! Reload from the server and the user - // (should) get the new manifest--unless the developer purged the static - // assets, the manifest path, but not the documents 😬 + // If we can't load the route it's likely one of 2 things: + // - User got caught in the middle of a deploy and the CDN no longer has the + // asset we're trying to import! Reload from the server and the user + // (should) get the new manifest--unless the developer purged the static + // assets, the manifest path, but not the documents 😬 + // - Or, the asset trying to be imported has an error (usually in vite dev + // mode), so the best we can do here is log the error for visibility + // (via `Preserve log`) and reload + + // Log the error so it can be accessed via the `Preserve Log` setting + console.error( + `Error loading route module \`${route.module}\`, reloading page...` + ); + console.error(error); + if ( window.__remixContext.isSpaMode && // @ts-expect-error @@ -203,10 +214,11 @@ export async function loadRouteModule( // on dev-time errors since it's a vite compilation error and a reload is // just going to fail with the same issue. Let the UI bubble to the error // boundary and let them see the error in the overlay or the dev server log - console.error(`Error loading route module \`${route.module}\`:`, error); throw error; } + window.location.reload(); + return new Promise(() => { // check out of this hook cause the DJs never gonna re[s]olve this }); From f8389c50499ca2e292ca73693b1a04a0f16494b7 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 12 Jul 2024 15:23:26 -0400 Subject: [PATCH 15/30] Adopt RR stabilized v7_skipActionErrorRevalidation flag (#9706) --- .changeset/quiet-pugs-allow.md | 6 +++ docs/guides/single-fetch.md | 2 +- integration/package.json | 2 +- packages/remix-dev/package.json | 2 +- packages/remix-react/browser.tsx | 2 +- packages/remix-react/package.json | 6 +-- packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/package.json | 4 +- pnpm-lock.yaml | 50 +++++++++++----------- 9 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 .changeset/quiet-pugs-allow.md diff --git a/.changeset/quiet-pugs-allow.md b/.changeset/quiet-pugs-allow.md new file mode 100644 index 00000000000..4b3919200c2 --- /dev/null +++ b/.changeset/quiet-pugs-allow.md @@ -0,0 +1,6 @@ +--- +"@remix-run/react": patch +--- + +Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood + - This also stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` diff --git a/docs/guides/single-fetch.md b/docs/guides/single-fetch.md index 09bdd52e854..5d8bfa4fec4 100644 --- a/docs/guides/single-fetch.md +++ b/docs/guides/single-fetch.md @@ -540,7 +540,7 @@ Previously, Remix would always revalidate all active loaders after _any_ action With Single Fetch, if an `action` returns or throws a `Response` with a `4xx/5xx` status code, Remix will _not revalidate_ loaders by default. If an `action` returns or throws anything that is not a 4xx/5xx Response, then the revalidation behavior is unchanged. The reasoning here is that in most cases, if you return a `4xx`/`5xx` Response, you didn't actually mutate any data so there is no need to reload data. -If you _want_ to continue revalidating one or more loaders after a 4xx/5xx action response, you can opt-into revalidation on a per-route basis by returning `true` from your [`shouldRevalidate`][should-revalidate] function. There is also a new `unstable_actionStatus` parameter passed to the function that you can use if you need to decide based on the action status code. +If you _want_ to continue revalidating one or more loaders after a 4xx/5xx action response, you can opt-into revalidation on a per-route basis by returning `true` from your [`shouldRevalidate`][should-revalidate] function. There is also a new `actionStatus` parameter passed to the function that you can use if you need to decide based on the action status code. Revalidation is handled via a `?_routes` query string parameter on the single fetch HTTP call which limits the loaders being called. This means that when you are doing fine-grained revalidation, you will have cache enumerations based on the routes being requested - but all of the information is in the URL so you should not need any special CDN configurations (as opposed to if this was done via a custom header that required your CDN to respect the `Vary` header). diff --git a/integration/package.json b/integration/package.json index 681b1fb88b9..99f37391530 100644 --- a/integration/package.json +++ b/integration/package.json @@ -14,7 +14,7 @@ "@remix-run/dev": "workspace:*", "@remix-run/express": "workspace:*", "@remix-run/node": "workspace:*", - "@remix-run/router": "1.17.1", + "@remix-run/router": "1.18.0-pre.0", "@remix-run/server-runtime": "workspace:*", "@types/express": "^4.17.9", "@vanilla-extract/css": "^1.10.0", diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 8384871652b..7a470c19d93 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -32,7 +32,7 @@ "@mdx-js/mdx": "^2.3.0", "@npmcli/package-json": "^4.0.1", "@remix-run/node": "workspace:*", - "@remix-run/router": "1.17.1", + "@remix-run/router": "1.18.0-pre.0", "@remix-run/server-runtime": "workspace:*", "@types/mdx": "^2.0.5", "@vanilla-extract/integration": "^6.2.0", diff --git a/packages/remix-react/browser.tsx b/packages/remix-react/browser.tsx index 2b995662647..c0014b1c1e1 100644 --- a/packages/remix-react/browser.tsx +++ b/packages/remix-react/browser.tsx @@ -326,7 +326,7 @@ export function RemixBrowser(_props: RemixBrowserProps): ReactElement { v7_prependBasename: true, v7_relativeSplatPath: window.__remixContext.future.v3_relativeSplatPath, // Single fetch enables this underlying behavior - unstable_skipActionErrorRevalidation: + v7_skipActionErrorRevalidation: window.__remixContext.future.unstable_singleFetch === true, }, hydrationData, diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 5bb9e5feff9..382d53757fa 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -19,10 +19,10 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "1.17.1", + "@remix-run/router": "1.18.0-pre.0", "@remix-run/server-runtime": "workspace:*", - "react-router": "6.24.1", - "react-router-dom": "6.24.1", + "react-router": "6.25.0-pre.0", + "react-router-dom": "6.25.0-pre.0", "turbo-stream": "2.2.0" }, "devDependencies": { diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 43a9db5cc0f..7409071d05b 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -19,7 +19,7 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "1.17.1", + "@remix-run/router": "1.18.0-pre.0", "@types/cookie": "^0.6.0", "@web3-storage/multipart-parser": "^1.0.0", "cookie": "^0.6.0", diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 6cc7347858b..633ac616418 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -21,8 +21,8 @@ "dependencies": { "@remix-run/node": "workspace:*", "@remix-run/react": "workspace:*", - "@remix-run/router": "1.17.1", - "react-router-dom": "6.24.1" + "@remix-run/router": "1.18.0-pre.0", + "react-router-dom": "6.25.0-pre.0" }, "devDependencies": { "@remix-run/server-runtime": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 65b97bab3a0..112aef24b80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -323,8 +323,8 @@ importers: specifier: workspace:* version: link:../packages/remix-node '@remix-run/router': - specifier: 1.17.1 - version: 1.17.1 + specifier: 1.18.0-pre.0 + version: 1.18.0-pre.0 '@remix-run/server-runtime': specifier: workspace:* version: link:../packages/remix-server-runtime @@ -871,8 +871,8 @@ importers: specifier: ^2.10.2 version: link:../remix-react '@remix-run/router': - specifier: 1.17.1 - version: 1.17.1 + specifier: 1.18.0-pre.0 + version: 1.18.0-pre.0 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime @@ -1217,17 +1217,17 @@ importers: packages/remix-react: dependencies: '@remix-run/router': - specifier: 1.17.1 - version: 1.17.1 + specifier: 1.18.0-pre.0 + version: 1.18.0-pre.0 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime react-router: - specifier: 6.24.1 - version: 6.24.1(react@18.2.0) + specifier: 6.25.0-pre.0 + version: 6.25.0-pre.0(react@18.2.0) react-router-dom: - specifier: 6.24.1 - version: 6.24.1(react-dom@18.2.0)(react@18.2.0) + specifier: 6.25.0-pre.0 + version: 6.25.0-pre.0(react-dom@18.2.0)(react@18.2.0) turbo-stream: specifier: 2.2.0 version: 2.2.0 @@ -1303,8 +1303,8 @@ importers: packages/remix-server-runtime: dependencies: '@remix-run/router': - specifier: 1.17.1 - version: 1.17.1 + specifier: 1.18.0-pre.0 + version: 1.18.0-pre.0 '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -1340,11 +1340,11 @@ importers: specifier: workspace:* version: link:../remix-react '@remix-run/router': - specifier: 1.17.1 - version: 1.17.1 + specifier: 1.18.0-pre.0 + version: 1.18.0-pre.0 react-router-dom: - specifier: 6.24.1 - version: 6.24.1(react-dom@18.2.0)(react@18.2.0) + specifier: 6.25.0-pre.0 + version: 6.25.0-pre.0(react-dom@18.2.0)(react@18.2.0) devDependencies: '@remix-run/server-runtime': specifier: workspace:* @@ -4201,8 +4201,8 @@ packages: - encoding dev: false - /@remix-run/router@1.17.1: - resolution: {integrity: sha512-mCOMec4BKd6BRGBZeSnGiIgwsbLGp3yhVqAD8H+PxiRNEHgDpZb8J1TnrSDlg97t0ySKMQJTHCWBCmBpSmkF6Q==} + /@remix-run/router@1.18.0-pre.0: + resolution: {integrity: sha512-Zo1fE2mPJCJyrUKW3+wpLXb/RWRZyBWmHxuaI9ar6D55qLxSDi8hJKtfGZT2buw4uM9n0q2f0/t0Omkirbf25w==} engines: {node: '>=14.0.0'} dev: false @@ -12786,26 +12786,26 @@ packages: engines: {node: '>=0.10.0'} dev: false - /react-router-dom@6.24.1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-U19KtXqooqw967Vw0Qcn5cOvrX5Ejo9ORmOtJMzYWtCT4/WOfFLIZGGsVLxcd9UkBO0mSTZtXqhZBsWlHr7+Sg==} + /react-router-dom@6.25.0-pre.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-RpL0UlhWxadZA1AAKqVoTRiu1PhdM9HSOI+UYu/N8keBSVc/k3s5/kfh+GlH1Z2/KGxlVsahb5wnO6zfpeetRQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.17.1 + '@remix-run/router': 1.18.0-pre.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.24.1(react@18.2.0) + react-router: 6.25.0-pre.0(react@18.2.0) dev: false - /react-router@6.24.1(react@18.2.0): - resolution: {integrity: sha512-PTXFXGK2pyXpHzVo3rR9H7ip4lSPZZc0bHG5CARmj65fTT6qG7sTngmb6lcYu1gf3y/8KxORoy9yn59pGpCnpg==} + /react-router@6.25.0-pre.0(react@18.2.0): + resolution: {integrity: sha512-5ein7idemBBQz6RsTEdjsQIIwFrjqpRsMqchPvvIAgeVz4Vv11qj1RYF0DRUUTgwJRkLxt5o0YmqvOWD/hgLOg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.17.1 + '@remix-run/router': 1.18.0-pre.0 react: 18.2.0 dev: false From 207a8d6140a8a585ae429ee3a20b52d16d7bb0ec Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Fri, 12 Jul 2024 19:24:55 +0000 Subject: [PATCH 16/30] chore: format --- .changeset/quiet-pugs-allow.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/quiet-pugs-allow.md b/.changeset/quiet-pugs-allow.md index 4b3919200c2..a1bc3a8cf0e 100644 --- a/.changeset/quiet-pugs-allow.md +++ b/.changeset/quiet-pugs-allow.md @@ -3,4 +3,5 @@ --- Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood - - This also stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` + +- This also stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` From 67a41a90048599fddc6fbb5bcdcb1ee14e846468 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 12 Jul 2024 15:27:21 -0400 Subject: [PATCH 17/30] Enter prerelease mode --- .changeset/pre.json | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 00000000000..e5643248906 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,29 @@ +{ + "mode": "pre", + "tag": "pre", + "initialVersions": { + "integration": "0.0.0", + "integration-cf-template": "0.0.0", + "integration-deno-template": "0.0.0", + "integration-node-template": "0.0.0", + "integration-vite-cloudflare-template": "0.0.0", + "integration-vite-template": "0.0.0", + "create-remix": "2.10.2", + "remix": "2.10.2", + "@remix-run/architect": "2.10.2", + "@remix-run/cloudflare": "2.10.2", + "@remix-run/cloudflare-pages": "2.10.2", + "@remix-run/cloudflare-workers": "2.10.2", + "@remix-run/css-bundle": "2.10.2", + "@remix-run/deno": "2.10.2", + "@remix-run/dev": "2.10.2", + "@remix-run/eslint-config": "2.10.2", + "@remix-run/express": "2.10.2", + "@remix-run/node": "2.10.2", + "@remix-run/react": "2.10.2", + "@remix-run/serve": "2.10.2", + "@remix-run/server-runtime": "2.10.2", + "@remix-run/testing": "2.10.2" + }, + "changesets": [] +} From 3718f8932414bdabe50022ee2d622588c73b5cbb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 12 Jul 2024 15:33:17 -0400 Subject: [PATCH 18/30] chore: Update version for release (pre) (#9745) Co-authored-by: github-actions[bot] Co-authored-by: Matt Brophy --- .changeset/pre.json | 7 +- CHANGELOG.md | 151 ++++++++++++------ .../vite-cloudflare-template/package.json | 6 +- packages/create-remix/CHANGELOG.md | 2 + packages/create-remix/package.json | 2 +- packages/remix-architect/CHANGELOG.md | 8 + packages/remix-architect/package.json | 2 +- packages/remix-cloudflare-pages/CHANGELOG.md | 7 + packages/remix-cloudflare-pages/package.json | 2 +- .../remix-cloudflare-workers/CHANGELOG.md | 7 + .../remix-cloudflare-workers/package.json | 2 +- packages/remix-cloudflare/CHANGELOG.md | 7 + packages/remix-cloudflare/package.json | 2 +- packages/remix-css-bundle/CHANGELOG.md | 2 + packages/remix-css-bundle/package.json | 2 +- packages/remix-deno/CHANGELOG.md | 7 + packages/remix-deno/package.json | 2 +- packages/remix-dev/CHANGELOG.md | 10 ++ packages/remix-dev/package.json | 6 +- packages/remix-eslint-config/CHANGELOG.md | 2 + packages/remix-eslint-config/package.json | 2 +- packages/remix-express/CHANGELOG.md | 7 + packages/remix-express/package.json | 2 +- packages/remix-node/CHANGELOG.md | 7 + packages/remix-node/package.json | 2 +- packages/remix-react/CHANGELOG.md | 13 ++ packages/remix-react/package.json | 2 +- packages/remix-serve/CHANGELOG.md | 8 + packages/remix-serve/package.json | 2 +- packages/remix-server-runtime/CHANGELOG.md | 2 + packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/CHANGELOG.md | 8 + packages/remix-testing/package.json | 2 +- packages/remix/package.json | 2 +- pnpm-lock.yaml | 8 +- 35 files changed, 226 insertions(+), 79 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index e5643248906..b007b74bf02 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -25,5 +25,10 @@ "@remix-run/server-runtime": "2.10.2", "@remix-run/testing": "2.10.2" }, - "changesets": [] + "changesets": [ + "few-planets-attend", + "fluffy-ways-bathe", + "log-module-error", + "quiet-pugs-allow" + ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 167e0eb90f9..93e955db11a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,47 +13,54 @@ We manage release notes in this file instead of the paginated Github Releases Pa Table of Contents - [Remix Releases](#remix-releases) - - [v2.10.1](#v2101) + - [v2.10.3](#v2103) - [Patch Changes](#patch-changes) - [Updated Dependencies](#updated-dependencies) - [Changes by Package](#changes-by-package) + - [v2.10.2](#v2102) + - [Patch Changes](#patch-changes-1) + - [Changes by Package](#changes-by-package-1) + - [v2.10.1](#v2101) + - [Patch Changes](#patch-changes-2) + - [Updated Dependencies](#updated-dependencies-1) + - [Changes by Package](#changes-by-package-2) - [v2.10.0](#v2100) - [What's Changed](#whats-changed) - [Lazy Route Discovery (a.k.a. "Fog of War")](#lazy-route-discovery-aka-fog-of-war) - [Minor Changes](#minor-changes) - - [Patch Changes](#patch-changes-1) - - [Updated Dependencies](#updated-dependencies-1) - - [Changes by Package](#changes-by-package-1) + - [Patch Changes](#patch-changes-3) + - [Updated Dependencies](#updated-dependencies-2) + - [Changes by Package](#changes-by-package-3) - [v2.9.2](#v292) - [What's Changed](#whats-changed-1) - [Updated Type-Safety for Single Fetch](#updated-type-safety-for-single-fetch) - - [Patch Changes](#patch-changes-2) - - [Updated Dependencies](#updated-dependencies-2) - - [Changes by Package](#changes-by-package-2) + - [Patch Changes](#patch-changes-4) + - [Updated Dependencies](#updated-dependencies-3) + - [Changes by Package](#changes-by-package-4) - [v2.9.1](#v291) - - [Patch Changes](#patch-changes-3) - - [Changes by Package](#changes-by-package-3) + - [Patch Changes](#patch-changes-5) + - [Changes by Package](#changes-by-package-5) - [v2.9.0](#v290) - [What's Changed](#whats-changed-2) - [Single Fetch (unstable)](#single-fetch-unstable) - [Undici](#undici) - [Minor Changes](#minor-changes-1) - - [Patch Changes](#patch-changes-4) - - [Updated Dependencies](#updated-dependencies-3) - - [Changes by Package](#changes-by-package-4) - - [v2.8.1](#v281) - - [Patch Changes](#patch-changes-5) + - [Patch Changes](#patch-changes-6) - [Updated Dependencies](#updated-dependencies-4) - - [Changes by Package](#changes-by-package-5) + - [Changes by Package](#changes-by-package-6) + - [v2.8.1](#v281) + - [Patch Changes](#patch-changes-7) + - [Updated Dependencies](#updated-dependencies-5) + - [Changes by Package](#changes-by-package-7) - [v2.8.0](#v280) - [Minor Changes](#minor-changes-2) - - [Patch Changes](#patch-changes-6) - - [Updated Dependencies](#updated-dependencies-5) - - [Changes by Package](#changes-by-package-6) + - [Patch Changes](#patch-changes-8) + - [Updated Dependencies](#updated-dependencies-6) + - [Changes by Package](#changes-by-package-8) - [2.7.2](#272) - - [Patch Changes](#patch-changes-7) + - [Patch Changes](#patch-changes-9) - [2.7.1](#271) - - [Patch Changes](#patch-changes-8) + - [Patch Changes](#patch-changes-10) - [v2.7.0](#v270) - [What's Changed](#whats-changed-3) - [Stabilized Vite Plugin](#stabilized-vite-plugin) @@ -61,72 +68,72 @@ We manage release notes in this file instead of the paginated Github Releases Pa - [Basename support](#basename-support) - [Cloudflare Proxy as a Vite Plugin](#cloudflare-proxy-as-a-vite-plugin) - [Minor Changes](#minor-changes-3) - - [Patch Changes](#patch-changes-9) - - [Updated Dependencies](#updated-dependencies-6) - - [Changes by Package](#changes-by-package-7) + - [Patch Changes](#patch-changes-11) + - [Updated Dependencies](#updated-dependencies-7) + - [Changes by Package](#changes-by-package-9) - [v2.6.0](#v260) - [What's Changed](#whats-changed-4) - [Unstable Vite Plugin updates](#unstable-vite-plugin-updates) - [Minor Changes](#minor-changes-4) - - [Patch Changes](#patch-changes-10) - - [Updated Dependencies](#updated-dependencies-7) - - [Changes by Package](#changes-by-package-8) - - [v2.5.1](#v251) - - [Patch Changes](#patch-changes-11) + - [Patch Changes](#patch-changes-12) - [Updated Dependencies](#updated-dependencies-8) - - [Changes by Package](#changes-by-package-9) + - [Changes by Package](#changes-by-package-10) + - [v2.5.1](#v251) + - [Patch Changes](#patch-changes-13) + - [Updated Dependencies](#updated-dependencies-9) + - [Changes by Package](#changes-by-package-11) - [v2.5.0](#v250) - [What's Changed](#whats-changed-5) - [SPA Mode (unstable)](#spa-mode-unstable) - [Server Bundles (unstable)](#server-bundles-unstable) - [Minor Changes](#minor-changes-5) - - [Patch Changes](#patch-changes-12) - - [Updated Dependencies](#updated-dependencies-9) - - [Changes by Package](#changes-by-package-10) - - [v2.4.1](#v241) - - [Patch Changes](#patch-changes-13) + - [Patch Changes](#patch-changes-14) - [Updated Dependencies](#updated-dependencies-10) - - [Changes by Package](#changes-by-package-11) + - [Changes by Package](#changes-by-package-12) + - [v2.4.1](#v241) + - [Patch Changes](#patch-changes-15) + - [Updated Dependencies](#updated-dependencies-11) + - [Changes by Package](#changes-by-package-13) - [v2.4.0](#v240) - [What's Changed](#whats-changed-6) - [Client Data](#client-data) - [`future.v3_relativeSplatPath`](#futurev3_relativesplatpath) - [Vite Updates (Unstable)](#vite-updates-unstable) - [Minor Changes](#minor-changes-6) - - [Patch Changes](#patch-changes-14) - - [Updated Dependencies](#updated-dependencies-11) - - [Changes by Package](#changes-by-package-12) - - [v2.3.1](#v231) - - [Patch Changes](#patch-changes-15) + - [Patch Changes](#patch-changes-16) - [Updated Dependencies](#updated-dependencies-12) - - [Changes by Package](#changes-by-package-13) + - [Changes by Package](#changes-by-package-14) + - [v2.3.1](#v231) + - [Patch Changes](#patch-changes-17) + - [Updated Dependencies](#updated-dependencies-13) + - [Changes by Package](#changes-by-package-15) - [v2.3.0](#v230) - [What's Changed](#whats-changed-7) - [Stabilized `useBlocker`](#stabilized-useblocker) - [`unstable_flushSync` API](#unstable_flushsync-api) - [Minor Changes](#minor-changes-7) - - [Patch Changes](#patch-changes-16) - - [Updated Dependencies](#updated-dependencies-13) - - [Changes by Package](#changes-by-package-14) + - [Patch Changes](#patch-changes-18) + - [Updated Dependencies](#updated-dependencies-14) + - [Changes by Package](#changes-by-package-16) - [v2.2.0](#v220) - [What's Changed](#whats-changed-8) - [Vite!](#vite) - [New Fetcher APIs](#new-fetcher-apis) - [Persistence Future Flag](#persistence-future-flag) - [Minor Changes](#minor-changes-8) - - [Patch Changes](#patch-changes-17) - - [Updated Dependencies](#updated-dependencies-14) - - [Changes by Package](#changes-by-package-15) + - [Patch Changes](#patch-changes-19) + - [Updated Dependencies](#updated-dependencies-15) + - [Changes by Package](#changes-by-package-17) - [v2.1.0](#v210) - [What's Changed](#whats-changed-9) - [View Transitions](#view-transitions) - [Stable `createRemixStub`](#stable-createremixstub) - [Minor Changes](#minor-changes-9) - - [Patch Changes](#patch-changes-18) - - [Updated Dependencies](#updated-dependencies-15) - - [Changes by Package](#changes-by-package-16) + - [Patch Changes](#patch-changes-20) + - [Updated Dependencies](#updated-dependencies-16) + - [Changes by Package](#changes-by-package-18) - [v2.0.1](#v201) - - [Patch Changes](#patch-changes-19) + - [Patch Changes](#patch-changes-21) - [Changes by Package 🔗](#changes-by-package-) - [v2.0.0](#v200) - [Breaking Changes](#breaking-changes) @@ -138,8 +145,8 @@ We manage release notes in this file instead of the paginated Github Releases Pa - [Breaking Type Changes](#breaking-type-changes) - [New Features](#new-features) - [Other Notable Changes](#other-notable-changes) - - [Updated Dependencies](#updated-dependencies-16) - - [Changes by Package](#changes-by-package-17) + - [Updated Dependencies](#updated-dependencies-17) + - [Changes by Package](#changes-by-package-19) @@ -187,6 +194,44 @@ Date: YYYY-MM-DD --> +## v2.10.3 + +Date: 2024-07-16 + +### Patch Changes + +- `@remix-run/architect` - Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation. ([#9664](https://github.com/remix-run/remix/pull/9664)) +- `@remix-run/react` - Log any errors encountered loading a route module prior to reloading the page ([#8932](https://github.com/remix-run/remix/pull/8932)) +- `@remix-run/react` - Single Fetch: Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) +- `@remix-run/react` - Single Fetch: Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood ([#9706](https://github.com/remix-run/remix/pull/9706)) + - This stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` + - ⚠️ This might be a breaking change for your app if you have opted into single fetch and the `unstable_actionStatus` parameter + +### Updated Dependencies + +- [`react-router-dom@6.25.0`](https://github.com/remix-run/react-router/releases/tag/react-router%406.25.0) +- [`@remix-run/router@1.18.0`](https://github.com/remix-run/react-router/blob/main/packages/router/CHANGELOG.md#1180) + +### Changes by Package + +- [`create-remix`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/create-remix/CHANGELOG.md#2103) +- [`@remix-run/architect`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-architect/CHANGELOG.md#2103) +- [`@remix-run/cloudflare`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-cloudflare/CHANGELOG.md#2103) +- [`@remix-run/cloudflare-pages`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-cloudflare-pages/CHANGELOG.md#2103) +- [`@remix-run/cloudflare-workers`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-cloudflare-workers/CHANGELOG.md#2103) +- [`@remix-run/css-bundle`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-css-bundle/CHANGELOG.md#2103) +- [`@remix-run/deno`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-deno/CHANGELOG.md#2103) +- [`@remix-run/dev`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-dev/CHANGELOG.md#2103) +- [`@remix-run/eslint-config`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-eslint-config/CHANGELOG.md#2103) +- [`@remix-run/express`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-express/CHANGELOG.md#2103) +- [`@remix-run/node`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-node/CHANGELOG.md#2103) +- [`@remix-run/react`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-react/CHANGELOG.md#2103) +- [`@remix-run/serve`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-serve/CHANGELOG.md#2103) +- [`@remix-run/server-runtime`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-server-runtime/CHANGELOG.md#2103) +- [`@remix-run/testing`](https://github.com/remix-run/remix/blob/remix%402.10.3/packages/remix-testing/CHANGELOG.md#2103) + +**Full Changelog**: [`v2.10.2...v2.10.3`](https://github.com/remix-run/remix/compare/remix@2.10.2...remix@2.10.3) + ## v2.10.2 Date: 2024-07-04 diff --git a/integration/helpers/vite-cloudflare-template/package.json b/integration/helpers/vite-cloudflare-template/package.json index f01a4bcbf3a..e9d5beddfc9 100644 --- a/integration/helpers/vite-cloudflare-template/package.json +++ b/integration/helpers/vite-cloudflare-template/package.json @@ -11,9 +11,9 @@ "typecheck": "tsc" }, "dependencies": { - "@remix-run/cloudflare": "2.10.2", - "@remix-run/cloudflare-pages": "2.10.2", - "@remix-run/react": "2.10.2", + "@remix-run/cloudflare": "2.10.3-pre.0", + "@remix-run/cloudflare-pages": "2.10.3-pre.0", + "@remix-run/react": "2.10.3-pre.0", "isbot": "^4.1.0", "miniflare": "^3.20231030.4", "react": "^18.2.0", diff --git a/packages/create-remix/CHANGELOG.md b/packages/create-remix/CHANGELOG.md index 63172c8485a..2c4479f5dd8 100644 --- a/packages/create-remix/CHANGELOG.md +++ b/packages/create-remix/CHANGELOG.md @@ -1,5 +1,7 @@ # `create-remix` +## 2.10.3-pre.0 + ## 2.10.2 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.2. diff --git a/packages/create-remix/package.json b/packages/create-remix/package.json index 9fae83053d5..af7a60a7c3e 100644 --- a/packages/create-remix/package.json +++ b/packages/create-remix/package.json @@ -1,6 +1,6 @@ { "name": "create-remix", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Create a new Remix app", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-architect/CHANGELOG.md b/packages/remix-architect/CHANGELOG.md index 5a5b8252609..72ff65e811b 100644 --- a/packages/remix-architect/CHANGELOG.md +++ b/packages/remix-architect/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/architect` +## 2.10.3-pre.0 + +### Patch Changes + +- Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation. ([#9664](https://github.com/remix-run/remix/pull/9664)) +- Updated dependencies: + - `@remix-run/node@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-architect/package.json b/packages/remix-architect/package.json index dcfdffaf0b1..13f08c4df9b 100644 --- a/packages/remix-architect/package.json +++ b/packages/remix-architect/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/architect", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Architect server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-pages/CHANGELOG.md b/packages/remix-cloudflare-pages/CHANGELOG.md index 8ac550bfd16..14082812f22 100644 --- a/packages/remix-cloudflare-pages/CHANGELOG.md +++ b/packages/remix-cloudflare-pages/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare-pages` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/cloudflare@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-cloudflare-pages/package.json b/packages/remix-cloudflare-pages/package.json index ab1d6b14ea1..34c25b3a8d1 100644 --- a/packages/remix-cloudflare-pages/package.json +++ b/packages/remix-cloudflare-pages/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-pages", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Cloudflare Pages request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-workers/CHANGELOG.md b/packages/remix-cloudflare-workers/CHANGELOG.md index c4d25388c51..df49ab3334b 100644 --- a/packages/remix-cloudflare-workers/CHANGELOG.md +++ b/packages/remix-cloudflare-workers/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare-workers` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/cloudflare@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-cloudflare-workers/package.json b/packages/remix-cloudflare-workers/package.json index 76fe9c8b112..a590d1a3687 100644 --- a/packages/remix-cloudflare-workers/package.json +++ b/packages/remix-cloudflare-workers/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-workers", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Cloudflare worker request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare/CHANGELOG.md b/packages/remix-cloudflare/CHANGELOG.md index fe9bf555395..623d1c37a3b 100644 --- a/packages/remix-cloudflare/CHANGELOG.md +++ b/packages/remix-cloudflare/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-cloudflare/package.json b/packages/remix-cloudflare/package.json index d5566b9aa49..4ee14acb6fb 100644 --- a/packages/remix-cloudflare/package.json +++ b/packages/remix-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Cloudflare platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-css-bundle/CHANGELOG.md b/packages/remix-css-bundle/CHANGELOG.md index d266a0d960a..b64357cc60e 100644 --- a/packages/remix-css-bundle/CHANGELOG.md +++ b/packages/remix-css-bundle/CHANGELOG.md @@ -1,5 +1,7 @@ # @remix-run/css-bundle +## 2.10.3-pre.0 + ## 2.10.2 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.2. diff --git a/packages/remix-css-bundle/package.json b/packages/remix-css-bundle/package.json index 11a31b7ea09..bb97ee02775 100644 --- a/packages/remix-css-bundle/package.json +++ b/packages/remix-css-bundle/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/css-bundle", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "CSS bundle href when using CSS bundling features in Remix", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-deno/CHANGELOG.md b/packages/remix-deno/CHANGELOG.md index cc3670f0599..26fcb19c2c0 100644 --- a/packages/remix-deno/CHANGELOG.md +++ b/packages/remix-deno/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/deno` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-deno/package.json b/packages/remix-deno/package.json index 73c7cf21e94..bb8caf123b1 100644 --- a/packages/remix-deno/package.json +++ b/packages/remix-deno/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/deno", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Deno platform abstractions for Remix", "homepage": "https://remix.run", "main": "./index.ts", diff --git a/packages/remix-dev/CHANGELOG.md b/packages/remix-dev/CHANGELOG.md index c1513d2b490..d9bba694c57 100644 --- a/packages/remix-dev/CHANGELOG.md +++ b/packages/remix-dev/CHANGELOG.md @@ -1,5 +1,15 @@ # `@remix-run/dev` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/react@2.10.3-pre.0` + - `@remix-run/node@2.10.3-pre.0` + - `@remix-run/serve@2.10.3-pre.0` + - `@remix-run/server-runtime@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 7a470c19d93..68e99a8ebe8 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/dev", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Dev tools and CLI for Remix", "homepage": "https://remix.run", "bugs": { @@ -106,8 +106,8 @@ "wrangler": "^3.28.2" }, "peerDependencies": { - "@remix-run/react": "^2.10.2", - "@remix-run/serve": "^2.10.2", + "@remix-run/react": "^2.10.3-pre.0", + "@remix-run/serve": "^2.10.3-pre.0", "typescript": "^5.1.0", "vite": "^5.1.0", "wrangler": "^3.28.2" diff --git a/packages/remix-eslint-config/CHANGELOG.md b/packages/remix-eslint-config/CHANGELOG.md index d4f72bbdc88..c8877465b55 100644 --- a/packages/remix-eslint-config/CHANGELOG.md +++ b/packages/remix-eslint-config/CHANGELOG.md @@ -1,5 +1,7 @@ # `@remix-run/eslint-config` +## 2.10.3-pre.0 + ## 2.10.2 No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.2. diff --git a/packages/remix-eslint-config/package.json b/packages/remix-eslint-config/package.json index 007b4bf94f6..1aa86f39c3d 100644 --- a/packages/remix-eslint-config/package.json +++ b/packages/remix-eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/eslint-config", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "ESLint configuration for Remix projects", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-express/CHANGELOG.md b/packages/remix-express/CHANGELOG.md index ab94fb4df49..c8d1a6eb9de 100644 --- a/packages/remix-express/CHANGELOG.md +++ b/packages/remix-express/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/express` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-express/package.json b/packages/remix-express/package.json index 85692db41ae..01106217384 100644 --- a/packages/remix-express/package.json +++ b/packages/remix-express/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/express", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Express server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-node/CHANGELOG.md b/packages/remix-node/CHANGELOG.md index 1de9ef0a36e..3f178375be1 100644 --- a/packages/remix-node/CHANGELOG.md +++ b/packages/remix-node/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/node` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-node/package.json b/packages/remix-node/package.json index be2241f0522..ed0c4b3b442 100644 --- a/packages/remix-node/package.json +++ b/packages/remix-node/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/node", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Node.js platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-react/CHANGELOG.md b/packages/remix-react/CHANGELOG.md index a1075384620..787ed7a30c5 100644 --- a/packages/remix-react/CHANGELOG.md +++ b/packages/remix-react/CHANGELOG.md @@ -1,5 +1,18 @@ # `@remix-run/react` +## 2.10.3-pre.0 + +### Patch Changes + +- Single Fetch: Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) +- Log any errors encountered loading a route module prior to reloading the page ([#8932](https://github.com/remix-run/remix/pull/8932)) +- Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood ([#9706](https://github.com/remix-run/remix/pull/9706)) + + - This also stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 382d53757fa..ae1deae9805 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/react", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "React DOM bindings for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-serve/CHANGELOG.md b/packages/remix-serve/CHANGELOG.md index d596e54fed7..94194481fcd 100644 --- a/packages/remix-serve/CHANGELOG.md +++ b/packages/remix-serve/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/serve` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/express@2.10.3-pre.0` + - `@remix-run/node@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-serve/package.json b/packages/remix-serve/package.json index 9b7d5866e22..63e67f47cbb 100644 --- a/packages/remix-serve/package.json +++ b/packages/remix-serve/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/serve", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Production application server for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-server-runtime/CHANGELOG.md b/packages/remix-server-runtime/CHANGELOG.md index 3acc0c9a40c..ef426d31bd3 100644 --- a/packages/remix-server-runtime/CHANGELOG.md +++ b/packages/remix-server-runtime/CHANGELOG.md @@ -1,5 +1,7 @@ # `@remix-run/server-runtime` +## 2.10.3-pre.0 + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 7409071d05b..7888f87bacb 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/server-runtime", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Server runtime for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-testing/CHANGELOG.md b/packages/remix-testing/CHANGELOG.md index c8fe037ce3c..a1e009e22a6 100644 --- a/packages/remix-testing/CHANGELOG.md +++ b/packages/remix-testing/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/testing` +## 2.10.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/react@2.10.3-pre.0` + - `@remix-run/node@2.10.3-pre.0` + ## 2.10.2 ### Patch Changes diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 633ac616418..16a5ccebdfe 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix/package.json b/packages/remix/package.json index d7ca9f846df..bee9ded077f 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "remix", - "version": "2.10.2", + "version": "2.10.3-pre.0", "description": "A framework for building better websites", "homepage": "https://remix.run", "bugs": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 112aef24b80..8d777eda256 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,13 +548,13 @@ importers: integration/helpers/vite-cloudflare-template: dependencies: '@remix-run/cloudflare': - specifier: 2.10.2 + specifier: 2.10.3-pre.0 version: link:../../../packages/remix-cloudflare '@remix-run/cloudflare-pages': - specifier: 2.10.2 + specifier: 2.10.3-pre.0 version: link:../../../packages/remix-cloudflare-pages '@remix-run/react': - specifier: 2.10.2 + specifier: 2.10.3-pre.0 version: link:../../../packages/remix-react isbot: specifier: ^4.1.0 @@ -868,7 +868,7 @@ importers: specifier: workspace:* version: link:../remix-node '@remix-run/react': - specifier: ^2.10.2 + specifier: ^2.10.3-pre.0 version: link:../remix-react '@remix-run/router': specifier: 1.18.0-pre.0 From 8cb8d29c83fe6c449886e18e2ee4b8af11b38687 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Tue, 16 Jul 2024 09:41:12 -0400 Subject: [PATCH 19/30] bump router (#9760) --- .changeset/spicy-dancers-look.md | 5 +++ integration/package.json | 2 +- packages/remix-dev/package.json | 2 +- packages/remix-react/package.json | 6 +-- packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/package.json | 4 +- pnpm-lock.yaml | 50 +++++++++++----------- 7 files changed, 38 insertions(+), 33 deletions(-) create mode 100644 .changeset/spicy-dancers-look.md diff --git a/.changeset/spicy-dancers-look.md b/.changeset/spicy-dancers-look.md new file mode 100644 index 00000000000..2a5c2e42de8 --- /dev/null +++ b/.changeset/spicy-dancers-look.md @@ -0,0 +1,5 @@ +--- +"@remix-run/react": patch +--- + +[REMOVE] Bump router diff --git a/integration/package.json b/integration/package.json index 99f37391530..afe282f095a 100644 --- a/integration/package.json +++ b/integration/package.json @@ -14,7 +14,7 @@ "@remix-run/dev": "workspace:*", "@remix-run/express": "workspace:*", "@remix-run/node": "workspace:*", - "@remix-run/router": "1.18.0-pre.0", + "@remix-run/router": "1.18.0", "@remix-run/server-runtime": "workspace:*", "@types/express": "^4.17.9", "@vanilla-extract/css": "^1.10.0", diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 68e99a8ebe8..72ce07b2848 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -32,7 +32,7 @@ "@mdx-js/mdx": "^2.3.0", "@npmcli/package-json": "^4.0.1", "@remix-run/node": "workspace:*", - "@remix-run/router": "1.18.0-pre.0", + "@remix-run/router": "1.18.0", "@remix-run/server-runtime": "workspace:*", "@types/mdx": "^2.0.5", "@vanilla-extract/integration": "^6.2.0", diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index ae1deae9805..83a07893554 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -19,10 +19,10 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "1.18.0-pre.0", + "@remix-run/router": "1.18.0", "@remix-run/server-runtime": "workspace:*", - "react-router": "6.25.0-pre.0", - "react-router-dom": "6.25.0-pre.0", + "react-router": "6.25.0", + "react-router-dom": "6.25.0", "turbo-stream": "2.2.0" }, "devDependencies": { diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 7888f87bacb..08afffe3d0d 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -19,7 +19,7 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "1.18.0-pre.0", + "@remix-run/router": "1.18.0", "@types/cookie": "^0.6.0", "@web3-storage/multipart-parser": "^1.0.0", "cookie": "^0.6.0", diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 16a5ccebdfe..f034598b068 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -21,8 +21,8 @@ "dependencies": { "@remix-run/node": "workspace:*", "@remix-run/react": "workspace:*", - "@remix-run/router": "1.18.0-pre.0", - "react-router-dom": "6.25.0-pre.0" + "@remix-run/router": "1.18.0", + "react-router-dom": "6.25.0" }, "devDependencies": { "@remix-run/server-runtime": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8d777eda256..03781074d7f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -323,8 +323,8 @@ importers: specifier: workspace:* version: link:../packages/remix-node '@remix-run/router': - specifier: 1.18.0-pre.0 - version: 1.18.0-pre.0 + specifier: 1.18.0 + version: 1.18.0 '@remix-run/server-runtime': specifier: workspace:* version: link:../packages/remix-server-runtime @@ -871,8 +871,8 @@ importers: specifier: ^2.10.3-pre.0 version: link:../remix-react '@remix-run/router': - specifier: 1.18.0-pre.0 - version: 1.18.0-pre.0 + specifier: 1.18.0 + version: 1.18.0 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime @@ -1217,17 +1217,17 @@ importers: packages/remix-react: dependencies: '@remix-run/router': - specifier: 1.18.0-pre.0 - version: 1.18.0-pre.0 + specifier: 1.18.0 + version: 1.18.0 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime react-router: - specifier: 6.25.0-pre.0 - version: 6.25.0-pre.0(react@18.2.0) + specifier: 6.25.0 + version: 6.25.0(react@18.2.0) react-router-dom: - specifier: 6.25.0-pre.0 - version: 6.25.0-pre.0(react-dom@18.2.0)(react@18.2.0) + specifier: 6.25.0 + version: 6.25.0(react-dom@18.2.0)(react@18.2.0) turbo-stream: specifier: 2.2.0 version: 2.2.0 @@ -1303,8 +1303,8 @@ importers: packages/remix-server-runtime: dependencies: '@remix-run/router': - specifier: 1.18.0-pre.0 - version: 1.18.0-pre.0 + specifier: 1.18.0 + version: 1.18.0 '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -1340,11 +1340,11 @@ importers: specifier: workspace:* version: link:../remix-react '@remix-run/router': - specifier: 1.18.0-pre.0 - version: 1.18.0-pre.0 + specifier: 1.18.0 + version: 1.18.0 react-router-dom: - specifier: 6.25.0-pre.0 - version: 6.25.0-pre.0(react-dom@18.2.0)(react@18.2.0) + specifier: 6.25.0 + version: 6.25.0(react-dom@18.2.0)(react@18.2.0) devDependencies: '@remix-run/server-runtime': specifier: workspace:* @@ -4201,8 +4201,8 @@ packages: - encoding dev: false - /@remix-run/router@1.18.0-pre.0: - resolution: {integrity: sha512-Zo1fE2mPJCJyrUKW3+wpLXb/RWRZyBWmHxuaI9ar6D55qLxSDi8hJKtfGZT2buw4uM9n0q2f0/t0Omkirbf25w==} + /@remix-run/router@1.18.0: + resolution: {integrity: sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==} engines: {node: '>=14.0.0'} dev: false @@ -12786,26 +12786,26 @@ packages: engines: {node: '>=0.10.0'} dev: false - /react-router-dom@6.25.0-pre.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-RpL0UlhWxadZA1AAKqVoTRiu1PhdM9HSOI+UYu/N8keBSVc/k3s5/kfh+GlH1Z2/KGxlVsahb5wnO6zfpeetRQ==} + /react-router-dom@6.25.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-BhcczgDWWgvGZxjDDGuGHrA8HrsSudilqTaRSBYLWDayvo1ClchNIDVt5rldqp6e7Dro5dEFx9Mzc+r292lN0w==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.18.0-pre.0 + '@remix-run/router': 1.18.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.25.0-pre.0(react@18.2.0) + react-router: 6.25.0(react@18.2.0) dev: false - /react-router@6.25.0-pre.0(react@18.2.0): - resolution: {integrity: sha512-5ein7idemBBQz6RsTEdjsQIIwFrjqpRsMqchPvvIAgeVz4Vv11qj1RYF0DRUUTgwJRkLxt5o0YmqvOWD/hgLOg==} + /react-router@6.25.0(react@18.2.0): + resolution: {integrity: sha512-bziKjCcDbcxgWS9WlWFcQIVZ2vJHnCP6DGpQDT0l+0PFDasfJKgzf9CM22eTyhFsZkjk8ApCdKjJwKtzqH80jQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.18.0-pre.0 + '@remix-run/router': 1.18.0 react: 18.2.0 dev: false From 911986a324f2fca54a11600d3d9ac71b057f5218 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 09:44:58 -0400 Subject: [PATCH 20/30] chore: Update version for release (pre) (#9761) Co-authored-by: github-actions[bot] --- .changeset/pre.json | 3 ++- integration/helpers/vite-cloudflare-template/package.json | 6 +++--- packages/create-remix/CHANGELOG.md | 2 ++ packages/create-remix/package.json | 2 +- packages/remix-architect/CHANGELOG.md | 7 +++++++ packages/remix-architect/package.json | 2 +- packages/remix-cloudflare-pages/CHANGELOG.md | 7 +++++++ packages/remix-cloudflare-pages/package.json | 2 +- packages/remix-cloudflare-workers/CHANGELOG.md | 7 +++++++ packages/remix-cloudflare-workers/package.json | 2 +- packages/remix-cloudflare/CHANGELOG.md | 7 +++++++ packages/remix-cloudflare/package.json | 2 +- packages/remix-css-bundle/CHANGELOG.md | 2 ++ packages/remix-css-bundle/package.json | 2 +- packages/remix-deno/CHANGELOG.md | 7 +++++++ packages/remix-deno/package.json | 2 +- packages/remix-dev/CHANGELOG.md | 8 ++++++++ packages/remix-dev/package.json | 6 +++--- packages/remix-eslint-config/CHANGELOG.md | 2 ++ packages/remix-eslint-config/package.json | 2 +- packages/remix-express/CHANGELOG.md | 7 +++++++ packages/remix-express/package.json | 2 +- packages/remix-node/CHANGELOG.md | 7 +++++++ packages/remix-node/package.json | 2 +- packages/remix-react/CHANGELOG.md | 8 ++++++++ packages/remix-react/package.json | 2 +- packages/remix-serve/CHANGELOG.md | 8 ++++++++ packages/remix-serve/package.json | 2 +- packages/remix-server-runtime/CHANGELOG.md | 2 ++ packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/CHANGELOG.md | 8 ++++++++ packages/remix-testing/package.json | 2 +- packages/remix/package.json | 2 +- pnpm-lock.yaml | 8 ++++---- 34 files changed, 116 insertions(+), 26 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index b007b74bf02..97947b9bb12 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -29,6 +29,7 @@ "few-planets-attend", "fluffy-ways-bathe", "log-module-error", - "quiet-pugs-allow" + "quiet-pugs-allow", + "spicy-dancers-look" ] } diff --git a/integration/helpers/vite-cloudflare-template/package.json b/integration/helpers/vite-cloudflare-template/package.json index e9d5beddfc9..8a5005a2b36 100644 --- a/integration/helpers/vite-cloudflare-template/package.json +++ b/integration/helpers/vite-cloudflare-template/package.json @@ -11,9 +11,9 @@ "typecheck": "tsc" }, "dependencies": { - "@remix-run/cloudflare": "2.10.3-pre.0", - "@remix-run/cloudflare-pages": "2.10.3-pre.0", - "@remix-run/react": "2.10.3-pre.0", + "@remix-run/cloudflare": "2.10.3-pre.1", + "@remix-run/cloudflare-pages": "2.10.3-pre.1", + "@remix-run/react": "2.10.3-pre.1", "isbot": "^4.1.0", "miniflare": "^3.20231030.4", "react": "^18.2.0", diff --git a/packages/create-remix/CHANGELOG.md b/packages/create-remix/CHANGELOG.md index 2c4479f5dd8..1ed575fe96e 100644 --- a/packages/create-remix/CHANGELOG.md +++ b/packages/create-remix/CHANGELOG.md @@ -1,5 +1,7 @@ # `create-remix` +## 2.10.3-pre.1 + ## 2.10.3-pre.0 ## 2.10.2 diff --git a/packages/create-remix/package.json b/packages/create-remix/package.json index af7a60a7c3e..2c0ccb2c934 100644 --- a/packages/create-remix/package.json +++ b/packages/create-remix/package.json @@ -1,6 +1,6 @@ { "name": "create-remix", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Create a new Remix app", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-architect/CHANGELOG.md b/packages/remix-architect/CHANGELOG.md index 72ff65e811b..88053c583a9 100644 --- a/packages/remix-architect/CHANGELOG.md +++ b/packages/remix-architect/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/architect` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-architect/package.json b/packages/remix-architect/package.json index 13f08c4df9b..90a5e553403 100644 --- a/packages/remix-architect/package.json +++ b/packages/remix-architect/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/architect", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Architect server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-pages/CHANGELOG.md b/packages/remix-cloudflare-pages/CHANGELOG.md index 14082812f22..418f4fc181b 100644 --- a/packages/remix-cloudflare-pages/CHANGELOG.md +++ b/packages/remix-cloudflare-pages/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare-pages` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/cloudflare@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-cloudflare-pages/package.json b/packages/remix-cloudflare-pages/package.json index 34c25b3a8d1..df638441a77 100644 --- a/packages/remix-cloudflare-pages/package.json +++ b/packages/remix-cloudflare-pages/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-pages", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Cloudflare Pages request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-workers/CHANGELOG.md b/packages/remix-cloudflare-workers/CHANGELOG.md index df49ab3334b..d28a88a418f 100644 --- a/packages/remix-cloudflare-workers/CHANGELOG.md +++ b/packages/remix-cloudflare-workers/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare-workers` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/cloudflare@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-cloudflare-workers/package.json b/packages/remix-cloudflare-workers/package.json index a590d1a3687..61d34b26ae0 100644 --- a/packages/remix-cloudflare-workers/package.json +++ b/packages/remix-cloudflare-workers/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-workers", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Cloudflare worker request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare/CHANGELOG.md b/packages/remix-cloudflare/CHANGELOG.md index 623d1c37a3b..2b6bc774346 100644 --- a/packages/remix-cloudflare/CHANGELOG.md +++ b/packages/remix-cloudflare/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/cloudflare` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-cloudflare/package.json b/packages/remix-cloudflare/package.json index 4ee14acb6fb..9170132f1ad 100644 --- a/packages/remix-cloudflare/package.json +++ b/packages/remix-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Cloudflare platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-css-bundle/CHANGELOG.md b/packages/remix-css-bundle/CHANGELOG.md index b64357cc60e..efbd757f9f6 100644 --- a/packages/remix-css-bundle/CHANGELOG.md +++ b/packages/remix-css-bundle/CHANGELOG.md @@ -1,5 +1,7 @@ # @remix-run/css-bundle +## 2.10.3-pre.1 + ## 2.10.3-pre.0 ## 2.10.2 diff --git a/packages/remix-css-bundle/package.json b/packages/remix-css-bundle/package.json index bb97ee02775..77da3379a7f 100644 --- a/packages/remix-css-bundle/package.json +++ b/packages/remix-css-bundle/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/css-bundle", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "CSS bundle href when using CSS bundling features in Remix", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-deno/CHANGELOG.md b/packages/remix-deno/CHANGELOG.md index 26fcb19c2c0..f16d2cedb1a 100644 --- a/packages/remix-deno/CHANGELOG.md +++ b/packages/remix-deno/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/deno` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-deno/package.json b/packages/remix-deno/package.json index bb8caf123b1..7eda173c598 100644 --- a/packages/remix-deno/package.json +++ b/packages/remix-deno/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/deno", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Deno platform abstractions for Remix", "homepage": "https://remix.run", "main": "./index.ts", diff --git a/packages/remix-dev/CHANGELOG.md b/packages/remix-dev/CHANGELOG.md index d9bba694c57..ea2765a35cd 100644 --- a/packages/remix-dev/CHANGELOG.md +++ b/packages/remix-dev/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/dev` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.3-pre.1` + - `@remix-run/server-runtime@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 72ce07b2848..b6cf7945826 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/dev", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Dev tools and CLI for Remix", "homepage": "https://remix.run", "bugs": { @@ -106,8 +106,8 @@ "wrangler": "^3.28.2" }, "peerDependencies": { - "@remix-run/react": "^2.10.3-pre.0", - "@remix-run/serve": "^2.10.3-pre.0", + "@remix-run/react": "^2.10.3-pre.1", + "@remix-run/serve": "^2.10.3-pre.1", "typescript": "^5.1.0", "vite": "^5.1.0", "wrangler": "^3.28.2" diff --git a/packages/remix-eslint-config/CHANGELOG.md b/packages/remix-eslint-config/CHANGELOG.md index c8877465b55..2bcb0569b8c 100644 --- a/packages/remix-eslint-config/CHANGELOG.md +++ b/packages/remix-eslint-config/CHANGELOG.md @@ -1,5 +1,7 @@ # `@remix-run/eslint-config` +## 2.10.3-pre.1 + ## 2.10.3-pre.0 ## 2.10.2 diff --git a/packages/remix-eslint-config/package.json b/packages/remix-eslint-config/package.json index 1aa86f39c3d..a3570e1368a 100644 --- a/packages/remix-eslint-config/package.json +++ b/packages/remix-eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/eslint-config", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "ESLint configuration for Remix projects", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-express/CHANGELOG.md b/packages/remix-express/CHANGELOG.md index c8d1a6eb9de..3be51a3fd1a 100644 --- a/packages/remix-express/CHANGELOG.md +++ b/packages/remix-express/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/express` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/node@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-express/package.json b/packages/remix-express/package.json index 01106217384..bbb11ec3bfd 100644 --- a/packages/remix-express/package.json +++ b/packages/remix-express/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/express", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Express server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-node/CHANGELOG.md b/packages/remix-node/CHANGELOG.md index 3f178375be1..e64c3547207 100644 --- a/packages/remix-node/CHANGELOG.md +++ b/packages/remix-node/CHANGELOG.md @@ -1,5 +1,12 @@ # `@remix-run/node` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-node/package.json b/packages/remix-node/package.json index ed0c4b3b442..e753a99abec 100644 --- a/packages/remix-node/package.json +++ b/packages/remix-node/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/node", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Node.js platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-react/CHANGELOG.md b/packages/remix-react/CHANGELOG.md index 787ed7a30c5..439ab2e2a74 100644 --- a/packages/remix-react/CHANGELOG.md +++ b/packages/remix-react/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/react` +## 2.10.3-pre.1 + +### Patch Changes + +- [REMOVE] Bump router ([#9760](https://github.com/remix-run/remix/pull/9760)) +- Updated dependencies: + - `@remix-run/server-runtime@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 83a07893554..32648e28ae2 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/react", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "React DOM bindings for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-serve/CHANGELOG.md b/packages/remix-serve/CHANGELOG.md index 94194481fcd..cb1a85a0da5 100644 --- a/packages/remix-serve/CHANGELOG.md +++ b/packages/remix-serve/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/serve` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/express@2.10.3-pre.1` + - `@remix-run/node@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-serve/package.json b/packages/remix-serve/package.json index 63e67f47cbb..ac59bd3da46 100644 --- a/packages/remix-serve/package.json +++ b/packages/remix-serve/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/serve", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Production application server for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-server-runtime/CHANGELOG.md b/packages/remix-server-runtime/CHANGELOG.md index ef426d31bd3..3d5a27f3040 100644 --- a/packages/remix-server-runtime/CHANGELOG.md +++ b/packages/remix-server-runtime/CHANGELOG.md @@ -1,5 +1,7 @@ # `@remix-run/server-runtime` +## 2.10.3-pre.1 + ## 2.10.3-pre.0 ## 2.10.2 diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 08afffe3d0d..cced5e193ce 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/server-runtime", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Server runtime for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-testing/CHANGELOG.md b/packages/remix-testing/CHANGELOG.md index a1e009e22a6..ef84b91d6ff 100644 --- a/packages/remix-testing/CHANGELOG.md +++ b/packages/remix-testing/CHANGELOG.md @@ -1,5 +1,13 @@ # `@remix-run/testing` +## 2.10.3-pre.1 + +### Patch Changes + +- Updated dependencies: + - `@remix-run/react@2.10.3-pre.1` + - `@remix-run/node@2.10.3-pre.1` + ## 2.10.3-pre.0 ### Patch Changes diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index f034598b068..9f8e59a7fb4 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix/package.json b/packages/remix/package.json index bee9ded077f..1b9036fea6a 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "remix", - "version": "2.10.3-pre.0", + "version": "2.10.3-pre.1", "description": "A framework for building better websites", "homepage": "https://remix.run", "bugs": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 03781074d7f..807dfb0ae1e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,13 +548,13 @@ importers: integration/helpers/vite-cloudflare-template: dependencies: '@remix-run/cloudflare': - specifier: 2.10.3-pre.0 + specifier: 2.10.3-pre.1 version: link:../../../packages/remix-cloudflare '@remix-run/cloudflare-pages': - specifier: 2.10.3-pre.0 + specifier: 2.10.3-pre.1 version: link:../../../packages/remix-cloudflare-pages '@remix-run/react': - specifier: 2.10.3-pre.0 + specifier: 2.10.3-pre.1 version: link:../../../packages/remix-react isbot: specifier: ^4.1.0 @@ -868,7 +868,7 @@ importers: specifier: workspace:* version: link:../remix-node '@remix-run/react': - specifier: ^2.10.3-pre.0 + specifier: ^2.10.3-pre.1 version: link:../remix-react '@remix-run/router': specifier: 1.18.0 From d0cc05ba45cc261e76ec8bdc8f4bfe57728bebdf Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Tue, 16 Jul 2024 09:45:17 -0400 Subject: [PATCH 21/30] Exit prerelease mode --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 97947b9bb12..953dd36c082 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "pre", "initialVersions": { "integration": "0.0.0", From b445154207a45f2046ac9fd4c1f853409494927f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:01:09 -0400 Subject: [PATCH 22/30] chore: Update version for release (#9762) Co-authored-by: github-actions[bot] Co-authored-by: Matt Brophy --- .changeset/few-planets-attend.md | 5 --- .changeset/fluffy-ways-bathe.md | 5 --- .changeset/log-module-error.md | 5 --- .changeset/pre.json | 35 ------------------- .changeset/quiet-pugs-allow.md | 7 ---- .changeset/spicy-dancers-look.md | 5 --- CHANGELOG.md | 6 ++-- .../vite-cloudflare-template/package.json | 6 ++-- packages/create-remix/CHANGELOG.md | 4 +-- packages/create-remix/package.json | 2 +- packages/remix-architect/CHANGELOG.md | 13 ++----- packages/remix-architect/package.json | 2 +- packages/remix-cloudflare-pages/CHANGELOG.md | 11 ++---- packages/remix-cloudflare-pages/package.json | 2 +- .../remix-cloudflare-workers/CHANGELOG.md | 11 ++---- .../remix-cloudflare-workers/package.json | 2 +- packages/remix-cloudflare/CHANGELOG.md | 11 ++---- packages/remix-cloudflare/package.json | 2 +- packages/remix-css-bundle/CHANGELOG.md | 4 +-- packages/remix-css-bundle/package.json | 2 +- packages/remix-deno/CHANGELOG.md | 11 ++---- packages/remix-deno/package.json | 2 +- packages/remix-dev/CHANGELOG.md | 16 ++------- packages/remix-dev/package.json | 6 ++-- packages/remix-eslint-config/CHANGELOG.md | 4 +-- packages/remix-eslint-config/package.json | 2 +- packages/remix-express/CHANGELOG.md | 11 ++---- packages/remix-express/package.json | 2 +- packages/remix-node/CHANGELOG.md | 11 ++---- packages/remix-node/package.json | 2 +- packages/remix-react/CHANGELOG.md | 16 ++------- packages/remix-react/package.json | 2 +- packages/remix-serve/CHANGELOG.md | 14 ++------ packages/remix-serve/package.json | 2 +- packages/remix-server-runtime/CHANGELOG.md | 4 +-- packages/remix-server-runtime/package.json | 2 +- packages/remix-testing/CHANGELOG.md | 14 ++------ packages/remix-testing/package.json | 2 +- packages/remix/package.json | 2 +- pnpm-lock.yaml | 8 ++--- 40 files changed, 63 insertions(+), 210 deletions(-) delete mode 100644 .changeset/few-planets-attend.md delete mode 100644 .changeset/fluffy-ways-bathe.md delete mode 100644 .changeset/log-module-error.md delete mode 100644 .changeset/pre.json delete mode 100644 .changeset/quiet-pugs-allow.md delete mode 100644 .changeset/spicy-dancers-look.md diff --git a/.changeset/few-planets-attend.md b/.changeset/few-planets-attend.md deleted file mode 100644 index 1777c4cd74f..00000000000 --- a/.changeset/few-planets-attend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/architect": patch ---- - -Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation. diff --git a/.changeset/fluffy-ways-bathe.md b/.changeset/fluffy-ways-bathe.md deleted file mode 100644 index 16cbe962953..00000000000 --- a/.changeset/fluffy-ways-bathe.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/react": patch ---- - -Single Fetch: Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation diff --git a/.changeset/log-module-error.md b/.changeset/log-module-error.md deleted file mode 100644 index 5db9a136451..00000000000 --- a/.changeset/log-module-error.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/react": patch ---- - -Log any errors encountered loading a route module prior to reloading the page diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 953dd36c082..00000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "mode": "exit", - "tag": "pre", - "initialVersions": { - "integration": "0.0.0", - "integration-cf-template": "0.0.0", - "integration-deno-template": "0.0.0", - "integration-node-template": "0.0.0", - "integration-vite-cloudflare-template": "0.0.0", - "integration-vite-template": "0.0.0", - "create-remix": "2.10.2", - "remix": "2.10.2", - "@remix-run/architect": "2.10.2", - "@remix-run/cloudflare": "2.10.2", - "@remix-run/cloudflare-pages": "2.10.2", - "@remix-run/cloudflare-workers": "2.10.2", - "@remix-run/css-bundle": "2.10.2", - "@remix-run/deno": "2.10.2", - "@remix-run/dev": "2.10.2", - "@remix-run/eslint-config": "2.10.2", - "@remix-run/express": "2.10.2", - "@remix-run/node": "2.10.2", - "@remix-run/react": "2.10.2", - "@remix-run/serve": "2.10.2", - "@remix-run/server-runtime": "2.10.2", - "@remix-run/testing": "2.10.2" - }, - "changesets": [ - "few-planets-attend", - "fluffy-ways-bathe", - "log-module-error", - "quiet-pugs-allow", - "spicy-dancers-look" - ] -} diff --git a/.changeset/quiet-pugs-allow.md b/.changeset/quiet-pugs-allow.md deleted file mode 100644 index a1bc3a8cf0e..00000000000 --- a/.changeset/quiet-pugs-allow.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@remix-run/react": patch ---- - -Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood - -- This also stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` diff --git a/.changeset/spicy-dancers-look.md b/.changeset/spicy-dancers-look.md deleted file mode 100644 index 2a5c2e42de8..00000000000 --- a/.changeset/spicy-dancers-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/react": patch ---- - -[REMOVE] Bump router diff --git a/CHANGELOG.md b/CHANGELOG.md index 93e955db11a..34342efe734 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -200,10 +200,10 @@ Date: 2024-07-16 ### Patch Changes -- `@remix-run/architect` - Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation. ([#9664](https://github.com/remix-run/remix/pull/9664)) +- `@remix-run/architect` - Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation ([#9664](https://github.com/remix-run/remix/pull/9664)) - `@remix-run/react` - Log any errors encountered loading a route module prior to reloading the page ([#8932](https://github.com/remix-run/remix/pull/8932)) -- `@remix-run/react` - Single Fetch: Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) -- `@remix-run/react` - Single Fetch: Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood ([#9706](https://github.com/remix-run/remix/pull/9706)) +- `@remix-run/react` - Single Fetch (unstable): Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) +- `@remix-run/react` - Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood ([#9706](https://github.com/remix-run/remix/pull/9706)) - This stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` - ⚠️ This might be a breaking change for your app if you have opted into single fetch and the `unstable_actionStatus` parameter diff --git a/integration/helpers/vite-cloudflare-template/package.json b/integration/helpers/vite-cloudflare-template/package.json index 8a5005a2b36..a91e9475c66 100644 --- a/integration/helpers/vite-cloudflare-template/package.json +++ b/integration/helpers/vite-cloudflare-template/package.json @@ -11,9 +11,9 @@ "typecheck": "tsc" }, "dependencies": { - "@remix-run/cloudflare": "2.10.3-pre.1", - "@remix-run/cloudflare-pages": "2.10.3-pre.1", - "@remix-run/react": "2.10.3-pre.1", + "@remix-run/cloudflare": "2.10.3", + "@remix-run/cloudflare-pages": "2.10.3", + "@remix-run/react": "2.10.3", "isbot": "^4.1.0", "miniflare": "^3.20231030.4", "react": "^18.2.0", diff --git a/packages/create-remix/CHANGELOG.md b/packages/create-remix/CHANGELOG.md index 1ed575fe96e..8d6d586c413 100644 --- a/packages/create-remix/CHANGELOG.md +++ b/packages/create-remix/CHANGELOG.md @@ -1,8 +1,8 @@ # `create-remix` -## 2.10.3-pre.1 +## 2.10.3 -## 2.10.3-pre.0 +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.3. ## 2.10.2 diff --git a/packages/create-remix/package.json b/packages/create-remix/package.json index 2c0ccb2c934..ed4f09d3ddb 100644 --- a/packages/create-remix/package.json +++ b/packages/create-remix/package.json @@ -1,6 +1,6 @@ { "name": "create-remix", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Create a new Remix app", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-architect/CHANGELOG.md b/packages/remix-architect/CHANGELOG.md index 88053c583a9..0c7454ba783 100644 --- a/packages/remix-architect/CHANGELOG.md +++ b/packages/remix-architect/CHANGELOG.md @@ -1,19 +1,12 @@ # `@remix-run/architect` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes +- Manually joining headers with semi-colons to avoid differences in Remix and `node`/`undici` `Headers` implementation ([#9664](https://github.com/remix-run/remix/pull/9664)) - Updated dependencies: - - `@remix-run/node@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Manually joining headers with semi-colons to avoid differences in Remix and node/undici Headers implementation. ([#9664](https://github.com/remix-run/remix/pull/9664)) -- Updated dependencies: - - `@remix-run/node@2.10.3-pre.0` + - `@remix-run/node@2.10.3` ## 2.10.2 diff --git a/packages/remix-architect/package.json b/packages/remix-architect/package.json index 90a5e553403..f96e6597fd5 100644 --- a/packages/remix-architect/package.json +++ b/packages/remix-architect/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/architect", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Architect server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-pages/CHANGELOG.md b/packages/remix-cloudflare-pages/CHANGELOG.md index 418f4fc181b..dfd626554fb 100644 --- a/packages/remix-cloudflare-pages/CHANGELOG.md +++ b/packages/remix-cloudflare-pages/CHANGELOG.md @@ -1,18 +1,11 @@ # `@remix-run/cloudflare-pages` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/cloudflare@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/cloudflare@2.10.3-pre.0` + - `@remix-run/cloudflare@2.10.3` ## 2.10.2 diff --git a/packages/remix-cloudflare-pages/package.json b/packages/remix-cloudflare-pages/package.json index df638441a77..188f5b70d3f 100644 --- a/packages/remix-cloudflare-pages/package.json +++ b/packages/remix-cloudflare-pages/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-pages", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Cloudflare Pages request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare-workers/CHANGELOG.md b/packages/remix-cloudflare-workers/CHANGELOG.md index d28a88a418f..48bbb19bc30 100644 --- a/packages/remix-cloudflare-workers/CHANGELOG.md +++ b/packages/remix-cloudflare-workers/CHANGELOG.md @@ -1,18 +1,11 @@ # `@remix-run/cloudflare-workers` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/cloudflare@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/cloudflare@2.10.3-pre.0` + - `@remix-run/cloudflare@2.10.3` ## 2.10.2 diff --git a/packages/remix-cloudflare-workers/package.json b/packages/remix-cloudflare-workers/package.json index 61d34b26ae0..ad1bfee5a4a 100644 --- a/packages/remix-cloudflare-workers/package.json +++ b/packages/remix-cloudflare-workers/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare-workers", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Cloudflare worker request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-cloudflare/CHANGELOG.md b/packages/remix-cloudflare/CHANGELOG.md index 2b6bc774346..5f7e30da7e3 100644 --- a/packages/remix-cloudflare/CHANGELOG.md +++ b/packages/remix-cloudflare/CHANGELOG.md @@ -1,18 +1,11 @@ # `@remix-run/cloudflare` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.0` + - `@remix-run/server-runtime@2.10.3` ## 2.10.2 diff --git a/packages/remix-cloudflare/package.json b/packages/remix-cloudflare/package.json index 9170132f1ad..f64ae7cb6d8 100644 --- a/packages/remix-cloudflare/package.json +++ b/packages/remix-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/cloudflare", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Cloudflare platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-css-bundle/CHANGELOG.md b/packages/remix-css-bundle/CHANGELOG.md index efbd757f9f6..43368453d7a 100644 --- a/packages/remix-css-bundle/CHANGELOG.md +++ b/packages/remix-css-bundle/CHANGELOG.md @@ -1,8 +1,8 @@ # @remix-run/css-bundle -## 2.10.3-pre.1 +## 2.10.3 -## 2.10.3-pre.0 +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.3. ## 2.10.2 diff --git a/packages/remix-css-bundle/package.json b/packages/remix-css-bundle/package.json index 77da3379a7f..f64b07290c3 100644 --- a/packages/remix-css-bundle/package.json +++ b/packages/remix-css-bundle/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/css-bundle", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "CSS bundle href when using CSS bundling features in Remix", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix-deno/CHANGELOG.md b/packages/remix-deno/CHANGELOG.md index f16d2cedb1a..5f55a7ea520 100644 --- a/packages/remix-deno/CHANGELOG.md +++ b/packages/remix-deno/CHANGELOG.md @@ -1,18 +1,11 @@ # `@remix-run/deno` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.0` + - `@remix-run/server-runtime@2.10.3` ## 2.10.2 diff --git a/packages/remix-deno/package.json b/packages/remix-deno/package.json index 7eda173c598..5bbf90d707e 100644 --- a/packages/remix-deno/package.json +++ b/packages/remix-deno/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/deno", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Deno platform abstractions for Remix", "homepage": "https://remix.run", "main": "./index.ts", diff --git a/packages/remix-dev/CHANGELOG.md b/packages/remix-dev/CHANGELOG.md index ea2765a35cd..5153c70388f 100644 --- a/packages/remix-dev/CHANGELOG.md +++ b/packages/remix-dev/CHANGELOG.md @@ -1,22 +1,12 @@ # `@remix-run/dev` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/node@2.10.3-pre.1` - - `@remix-run/server-runtime@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.10.3-pre.0` - - `@remix-run/node@2.10.3-pre.0` - - `@remix-run/serve@2.10.3-pre.0` - - `@remix-run/server-runtime@2.10.3-pre.0` + - `@remix-run/node@2.10.3` + - `@remix-run/server-runtime@2.10.3` ## 2.10.2 diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index b6cf7945826..26f81834309 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/dev", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Dev tools and CLI for Remix", "homepage": "https://remix.run", "bugs": { @@ -106,8 +106,8 @@ "wrangler": "^3.28.2" }, "peerDependencies": { - "@remix-run/react": "^2.10.3-pre.1", - "@remix-run/serve": "^2.10.3-pre.1", + "@remix-run/react": "^2.10.3", + "@remix-run/serve": "^2.10.3", "typescript": "^5.1.0", "vite": "^5.1.0", "wrangler": "^3.28.2" diff --git a/packages/remix-eslint-config/CHANGELOG.md b/packages/remix-eslint-config/CHANGELOG.md index 2bcb0569b8c..729e8a6e23e 100644 --- a/packages/remix-eslint-config/CHANGELOG.md +++ b/packages/remix-eslint-config/CHANGELOG.md @@ -1,8 +1,8 @@ # `@remix-run/eslint-config` -## 2.10.3-pre.1 +## 2.10.3 -## 2.10.3-pre.0 +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.3. ## 2.10.2 diff --git a/packages/remix-eslint-config/package.json b/packages/remix-eslint-config/package.json index a3570e1368a..def596d3f37 100644 --- a/packages/remix-eslint-config/package.json +++ b/packages/remix-eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/eslint-config", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "ESLint configuration for Remix projects", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-express/CHANGELOG.md b/packages/remix-express/CHANGELOG.md index 3be51a3fd1a..04e3be23be3 100644 --- a/packages/remix-express/CHANGELOG.md +++ b/packages/remix-express/CHANGELOG.md @@ -1,18 +1,11 @@ # `@remix-run/express` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/node@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/node@2.10.3-pre.0` + - `@remix-run/node@2.10.3` ## 2.10.2 diff --git a/packages/remix-express/package.json b/packages/remix-express/package.json index bbb11ec3bfd..2ba9dc378e7 100644 --- a/packages/remix-express/package.json +++ b/packages/remix-express/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/express", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Express server request handler for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-node/CHANGELOG.md b/packages/remix-node/CHANGELOG.md index e64c3547207..7c57dea0ee3 100644 --- a/packages/remix-node/CHANGELOG.md +++ b/packages/remix-node/CHANGELOG.md @@ -1,18 +1,11 @@ # `@remix-run/node` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.0` + - `@remix-run/server-runtime@2.10.3` ## 2.10.2 diff --git a/packages/remix-node/package.json b/packages/remix-node/package.json index e753a99abec..c9a172b50f1 100644 --- a/packages/remix-node/package.json +++ b/packages/remix-node/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/node", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Node.js platform abstractions for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-react/CHANGELOG.md b/packages/remix-react/CHANGELOG.md index 439ab2e2a74..7bf260174a2 100644 --- a/packages/remix-react/CHANGELOG.md +++ b/packages/remix-react/CHANGELOG.md @@ -1,25 +1,15 @@ # `@remix-run/react` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes -- [REMOVE] Bump router ([#9760](https://github.com/remix-run/remix/pull/9760)) -- Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Single Fetch: Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) - Log any errors encountered loading a route module prior to reloading the page ([#8932](https://github.com/remix-run/remix/pull/8932)) +- Single Fetch (unstable): Proxy `request.signal` through `dataStrategy` for `loader` calls to fix cancellation ([#9738](https://github.com/remix-run/remix/pull/9738)) - Single Fetch (unstable): Adopt React Router's stabilized `future.v7_skipActionErrorRevalidation` under the hood ([#9706](https://github.com/remix-run/remix/pull/9706)) - - This also stabilizes the `shouldRevalidate` parameter from `unstable_actionStatus` to `actionStatus` - - Updated dependencies: - - `@remix-run/server-runtime@2.10.3-pre.0` + - `@remix-run/server-runtime@2.10.3` ## 2.10.2 diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 32648e28ae2..b15bcaf608e 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/react", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "React DOM bindings for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-serve/CHANGELOG.md b/packages/remix-serve/CHANGELOG.md index cb1a85a0da5..7ac9b29e065 100644 --- a/packages/remix-serve/CHANGELOG.md +++ b/packages/remix-serve/CHANGELOG.md @@ -1,20 +1,12 @@ # `@remix-run/serve` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/express@2.10.3-pre.1` - - `@remix-run/node@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/express@2.10.3-pre.0` - - `@remix-run/node@2.10.3-pre.0` + - `@remix-run/express@2.10.3` + - `@remix-run/node@2.10.3` ## 2.10.2 diff --git a/packages/remix-serve/package.json b/packages/remix-serve/package.json index ac59bd3da46..064f85940f2 100644 --- a/packages/remix-serve/package.json +++ b/packages/remix-serve/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/serve", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Production application server for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-server-runtime/CHANGELOG.md b/packages/remix-server-runtime/CHANGELOG.md index 3d5a27f3040..f828cb4fafd 100644 --- a/packages/remix-server-runtime/CHANGELOG.md +++ b/packages/remix-server-runtime/CHANGELOG.md @@ -1,8 +1,8 @@ # `@remix-run/server-runtime` -## 2.10.3-pre.1 +## 2.10.3 -## 2.10.3-pre.0 +No significant changes to this package were made in this release. [See the repo `CHANGELOG.md`](https://github.com/remix-run/remix/blob/main/CHANGELOG.md) for an overview of all changes in v2.10.3. ## 2.10.2 diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index cced5e193ce..0e5634c1f82 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/server-runtime", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Server runtime for Remix", "bugs": { "url": "https://github.com/remix-run/remix/issues" diff --git a/packages/remix-testing/CHANGELOG.md b/packages/remix-testing/CHANGELOG.md index ef84b91d6ff..63af3b8fb42 100644 --- a/packages/remix-testing/CHANGELOG.md +++ b/packages/remix-testing/CHANGELOG.md @@ -1,20 +1,12 @@ # `@remix-run/testing` -## 2.10.3-pre.1 +## 2.10.3 ### Patch Changes - Updated dependencies: - - `@remix-run/react@2.10.3-pre.1` - - `@remix-run/node@2.10.3-pre.1` - -## 2.10.3-pre.0 - -### Patch Changes - -- Updated dependencies: - - `@remix-run/react@2.10.3-pre.0` - - `@remix-run/node@2.10.3-pre.0` + - `@remix-run/react@2.10.3` + - `@remix-run/node@2.10.3` ## 2.10.2 diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index 9f8e59a7fb4..bbdff38fb78 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -1,6 +1,6 @@ { "name": "@remix-run/testing", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "Testing utilities for Remix apps", "homepage": "https://remix.run", "bugs": { diff --git a/packages/remix/package.json b/packages/remix/package.json index 1b9036fea6a..ef839f2ce67 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "remix", - "version": "2.10.3-pre.1", + "version": "2.10.3", "description": "A framework for building better websites", "homepage": "https://remix.run", "bugs": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 807dfb0ae1e..5c752534cdc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -548,13 +548,13 @@ importers: integration/helpers/vite-cloudflare-template: dependencies: '@remix-run/cloudflare': - specifier: 2.10.3-pre.1 + specifier: 2.10.3 version: link:../../../packages/remix-cloudflare '@remix-run/cloudflare-pages': - specifier: 2.10.3-pre.1 + specifier: 2.10.3 version: link:../../../packages/remix-cloudflare-pages '@remix-run/react': - specifier: 2.10.3-pre.1 + specifier: 2.10.3 version: link:../../../packages/remix-react isbot: specifier: ^4.1.0 @@ -868,7 +868,7 @@ importers: specifier: workspace:* version: link:../remix-node '@remix-run/react': - specifier: ^2.10.3-pre.1 + specifier: ^2.10.3 version: link:../remix-react '@remix-run/router': specifier: 1.18.0 From 629ae997dd12d3745b45374653e334cddf9f3876 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 18 Jul 2024 08:37:53 -0400 Subject: [PATCH 23/30] Rename future flag from fogOfWar to lazyRouteDiscovery (#9763) --- .changeset/happy-dots-sleep.md | 8 ++++++ docs/components/link.md | 4 +-- ...{fog-of-war.md => lazy-route-discovery.md} | 7 ++--- docs/start/future-flags.md | 6 ++--- integration/fog-of-war-test.ts | 26 +++++++++---------- integration/prefetch-test.ts | 2 +- .../remix-dev/__tests__/readConfig-test.ts | 2 +- packages/remix-dev/config.ts | 9 ++++--- packages/remix-react/entry.ts | 2 +- packages/remix-react/fog-of-war.ts | 2 +- packages/remix-server-runtime/entry.ts | 2 +- packages/remix-testing/create-remix-stub.tsx | 3 ++- 12 files changed, 42 insertions(+), 31 deletions(-) create mode 100644 .changeset/happy-dots-sleep.md rename docs/guides/{fog-of-war.md => lazy-route-discovery.md} (89%) diff --git a/.changeset/happy-dots-sleep.md b/.changeset/happy-dots-sleep.md new file mode 100644 index 00000000000..240fe64b436 --- /dev/null +++ b/.changeset/happy-dots-sleep.md @@ -0,0 +1,8 @@ +--- +"@remix-run/dev": minor +"@remix-run/react": minor +"@remix-run/server-runtime": minor +"@remix-run/testing": minor +--- + +Rename `future.unstable_fogOfWar` to `future.unstable_lazyRouteDiscovery` for clarity diff --git a/docs/components/link.md b/docs/components/link.md index 161a05755c6..1e6ddb4f08e 100644 --- a/docs/components/link.md +++ b/docs/components/link.md @@ -40,7 +40,7 @@ You can also pass a `Partial` value: ### `discover` -Defines the route discovery behavior when using [`future.unstable_fogOfWar`][fog-of-war]. +Defines the route discovery behavior when using [`future.unstable_lazyRouteDiscovery`][lazy-route-discovery]. ```tsx <> @@ -236,4 +236,4 @@ Please note that this API is marked unstable and may be subject to breaking chan [document-start-view-transition]: https://developer.mozilla.org/en-US/docs/Web/API/Document/startViewTransition [use-view-transition-state]: ../hooks/use-view-transition-state [relativesplatpath]: ../hooks/use-resolved-path#splat-paths -[fog-of-war]: ../guides/fog-of-war +[lazy-route-discovery]: ../guides/lazy-route-discovery diff --git a/docs/guides/fog-of-war.md b/docs/guides/lazy-route-discovery.md similarity index 89% rename from docs/guides/fog-of-war.md rename to docs/guides/lazy-route-discovery.md index 26b6df927c7..bd2a3c2d079 100644 --- a/docs/guides/fog-of-war.md +++ b/docs/guides/lazy-route-discovery.md @@ -1,12 +1,12 @@ --- -title: Fog of War +title: Lazy Route Discovery --- -# Fog Of War +# Lazy Route Discovery (a.k.a. "Fog of War") This is an unstable API and will continue to change, do not adopt in production -Remix introduced support for "Fog of War" ([RFC][rfc]) behind the `future.unstable_fogOfWar` [Future Flag][future-flags] in [`v2.10.0`][2.10.0]. This allows you to opt-into this behavior which will become the default in the next major version of Remix - a.k.a. React Router v7 ([1][rr-v7], [2][rr-v7-2]). +Remix introduced support for Lazy Route Discovery (a.k.a. "Fog of War") ([RFC][rfc]) behind the `future.unstable_lazyRouteDiscovery` [Future Flag][future-flags] in [`v2.10.0`][2.10.0]. This allows you to opt-into this behavior which will become the default in the next major version of Remix - a.k.a. React Router v7 ([1][rr-v7], [2][rr-v7-2]). For more information on this feature, please check out the [blog post][blog-post]. ## Current Behavior @@ -61,3 +61,4 @@ If you wish to opt-out of this eager route discovery on a per-link basis, you ca [link-discover]: ../components/link#discover [rr-v7]: https://remix.run/blog/merging-remix-and-react-router [rr-v7-2]: https://remix.run/blog/incremental-path-to-react-19 +[blog-post]: https://remix.run/blog/fog-of-war diff --git a/docs/start/future-flags.md b/docs/start/future-flags.md index 520c7c23ba2..a262544c0a7 100644 --- a/docs/start/future-flags.md +++ b/docs/start/future-flags.md @@ -336,15 +336,15 @@ You likely won't need to adjust any code, unless you had custom logic inside of Opt into [Single Fetch][single-fetch] behavior (details will be expanded once the flag stabilizes). -## unstable_fogOfWar +## unstable_lazyRouteDiscovery -Opt into [Fog of War][fog-of-war] behavior (details will be expanded once the flag stabilizes). +Opt into [Lazy Route Discovery][lazy-route-discovery] behavior (details will be expanded once the flag stabilizes). [development-strategy]: ../guides/api-development-strategy [fetcherpersist-rfc]: https://github.com/remix-run/remix/discussions/7698 [relativesplatpath-changelog]: https://github.com/remix-run/remix/blob/main/CHANGELOG.md#futurev3_relativesplatpath [single-fetch]: ../guides/single-fetch -[fog-of-war]: ../guides/fog-of-war +[lazy-route-discovery]: ../guides/lazy-route-discovery [vite]: https://vitejs.dev [vite-docs]: ../guides/vite [supported-remix-config-options]: ../file-conventions/vite-config diff --git a/integration/fog-of-war-test.ts b/integration/fog-of-war-test.ts index d7d33ae2640..70f209b238a 100644 --- a/integration/fog-of-war-test.ts +++ b/integration/fog-of-war-test.ts @@ -106,7 +106,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -152,7 +152,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: getFiles(), @@ -176,7 +176,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: getFiles(), @@ -211,7 +211,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: getFiles(), @@ -244,7 +244,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -310,7 +310,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -371,7 +371,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -422,7 +422,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -486,7 +486,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -534,7 +534,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -605,7 +605,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -721,7 +721,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { @@ -845,7 +845,7 @@ test.describe("Fog of War", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, }, }, files: { diff --git a/integration/prefetch-test.ts b/integration/prefetch-test.ts index 9cd2ba196a9..111f4006e7e 100644 --- a/integration/prefetch-test.ts +++ b/integration/prefetch-test.ts @@ -725,7 +725,7 @@ test.describe("single fetch", () => { let fixture = await createFixture({ config: { future: { - unstable_fogOfWar: true, + unstable_lazyRouteDiscovery: true, unstable_singleFetch: true, }, }, diff --git a/packages/remix-dev/__tests__/readConfig-test.ts b/packages/remix-dev/__tests__/readConfig-test.ts index c4934fd2cca..7803b6db9c4 100644 --- a/packages/remix-dev/__tests__/readConfig-test.ts +++ b/packages/remix-dev/__tests__/readConfig-test.ts @@ -36,7 +36,7 @@ describe("readConfig", () => { "entryServerFile": "entry.server.tsx", "entryServerFilePath": Any, "future": { - "unstable_fogOfWar": false, + "unstable_lazyRouteDiscovery": false, "unstable_singleFetch": false, "v3_fetcherPersist": false, "v3_relativeSplatPath": false, diff --git a/packages/remix-dev/config.ts b/packages/remix-dev/config.ts index 133097be682..8f993d61888 100644 --- a/packages/remix-dev/config.ts +++ b/packages/remix-dev/config.ts @@ -38,7 +38,7 @@ interface FutureConfig { v3_relativeSplatPath: boolean; v3_throwAbortReason: boolean; unstable_singleFetch: boolean; - unstable_fogOfWar: boolean; + unstable_lazyRouteDiscovery: boolean; } type NodeBuiltinsPolyfillOptions = Pick< @@ -528,9 +528,9 @@ export async function resolveConfig( entryServerFile = `entry.server.${serverRuntime}.tsx`; } - if (isSpaMode && appConfig.future?.unstable_fogOfWar === true) { + if (isSpaMode && appConfig.future?.unstable_lazyRouteDiscovery === true) { throw new Error( - "You can not use `future.unstable_fogOfWar` in SPA Mode (`ssr: false`)" + "You can not use `future.unstable_lazyRouteDiscovery` in SPA Mode (`ssr: false`)" ); } @@ -609,7 +609,8 @@ export async function resolveConfig( v3_relativeSplatPath: appConfig.future?.v3_relativeSplatPath === true, v3_throwAbortReason: appConfig.future?.v3_throwAbortReason === true, unstable_singleFetch: appConfig.future?.unstable_singleFetch === true, - unstable_fogOfWar: appConfig.future?.unstable_fogOfWar === true, + unstable_lazyRouteDiscovery: + appConfig.future?.unstable_lazyRouteDiscovery === true, }; if (appConfig.future) { diff --git a/packages/remix-react/entry.ts b/packages/remix-react/entry.ts index 180e88aa5be..51224341a2a 100644 --- a/packages/remix-react/entry.ts +++ b/packages/remix-react/entry.ts @@ -43,7 +43,7 @@ export interface EntryContext extends RemixContextObject { export interface FutureConfig { v3_fetcherPersist: boolean; v3_relativeSplatPath: boolean; - unstable_fogOfWar: boolean; + unstable_lazyRouteDiscovery: boolean; unstable_singleFetch: boolean; } diff --git a/packages/remix-react/fog-of-war.ts b/packages/remix-react/fog-of-war.ts index 92565bba0bb..d2fd22ecdbb 100644 --- a/packages/remix-react/fog-of-war.ts +++ b/packages/remix-react/fog-of-war.ts @@ -31,7 +31,7 @@ const URL_LIMIT = 7680; let fogOfWar: FogOfWarInfo | null = null; export function isFogOfWarEnabled(future: FutureConfig, isSpaMode: boolean) { - return future.unstable_fogOfWar === true && !isSpaMode; + return future.unstable_lazyRouteDiscovery === true && !isSpaMode; } export function getPartialManifest(manifest: AssetsManifest, router: Router) { diff --git a/packages/remix-server-runtime/entry.ts b/packages/remix-server-runtime/entry.ts index 3c475abea05..6cb3c2ee8ba 100644 --- a/packages/remix-server-runtime/entry.ts +++ b/packages/remix-server-runtime/entry.ts @@ -33,7 +33,7 @@ export interface FutureConfig { v3_fetcherPersist: boolean; v3_relativeSplatPath: boolean; v3_throwAbortReason: boolean; - unstable_fogOfWar: boolean; + unstable_lazyRouteDiscovery: boolean; unstable_singleFetch: boolean; } diff --git a/packages/remix-testing/create-remix-stub.tsx b/packages/remix-testing/create-remix-stub.tsx index fb28bdcf15f..72d41aa6ce1 100644 --- a/packages/remix-testing/create-remix-stub.tsx +++ b/packages/remix-testing/create-remix-stub.tsx @@ -106,7 +106,8 @@ export function createRemixStub( future: { v3_fetcherPersist: future?.v3_fetcherPersist === true, v3_relativeSplatPath: future?.v3_relativeSplatPath === true, - unstable_fogOfWar: future?.unstable_fogOfWar === true, + unstable_lazyRouteDiscovery: + future?.unstable_lazyRouteDiscovery === true, unstable_singleFetch: future?.unstable_singleFetch === true, }, manifest: { From 2c8eecd3788f38ad13c65cdb31fa4e29f16fb33a Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 18 Jul 2024 09:39:53 -0400 Subject: [PATCH 24/30] Add support for replace() redirects (#9764) --- .changeset/curvy-vans-remember.md | 9 +++ integration/package.json | 2 +- integration/redirects-test.ts | 80 +++++++++++++++++++ integration/single-fetch-test.ts | 65 +++++++++++++++ packages/remix-cloudflare/index.ts | 1 + packages/remix-deno/index.ts | 1 + packages/remix-dev/package.json | 2 +- packages/remix-node/index.ts | 1 + packages/remix-react/index.tsx | 1 + packages/remix-react/package.json | 6 +- packages/remix-react/routes.tsx | 4 + packages/remix-react/single-fetch.tsx | 3 + packages/remix-server-runtime/index.ts | 2 +- packages/remix-server-runtime/package.json | 2 +- packages/remix-server-runtime/responses.ts | 11 +++ packages/remix-server-runtime/single-fetch.ts | 2 + packages/remix-testing/package.json | 4 +- pnpm-lock.yaml | 50 ++++++------ 18 files changed, 212 insertions(+), 34 deletions(-) create mode 100644 .changeset/curvy-vans-remember.md diff --git a/.changeset/curvy-vans-remember.md b/.changeset/curvy-vans-remember.md new file mode 100644 index 00000000000..9ce451a7ae6 --- /dev/null +++ b/.changeset/curvy-vans-remember.md @@ -0,0 +1,9 @@ +--- +"@remix-run/cloudflare": minor +"@remix-run/deno": minor +"@remix-run/node": minor +"@remix-run/react": minor +"@remix-run/server-runtime": minor +--- + +Add a new `replace(url, init?)` alternative to `redirect(url, init?)` that performs a `history.replaceState` instead of a `history.pushState` on client-side navigation redirects diff --git a/integration/package.json b/integration/package.json index afe282f095a..db21212335a 100644 --- a/integration/package.json +++ b/integration/package.json @@ -14,7 +14,7 @@ "@remix-run/dev": "workspace:*", "@remix-run/express": "workspace:*", "@remix-run/node": "workspace:*", - "@remix-run/router": "1.18.0", + "@remix-run/router": "0.0.0-experimental-cffa549a1", "@remix-run/server-runtime": "workspace:*", "@types/express": "^4.17.9", "@vanilla-extract/css": "^1.10.0", diff --git a/integration/redirects-test.ts b/integration/redirects-test.ts index e9723bb8709..77f2fe49903 100644 --- a/integration/redirects-test.ts +++ b/integration/redirects-test.ts @@ -98,6 +98,34 @@ test.describe("redirects", () => { return

Hello B!

} `, + + "app/routes/replace.a.tsx": js` + import { Link } from "@remix-run/react"; + export default function () { + return <>

A

Go to B; + } + `, + + "app/routes/replace.b.tsx": js` + import { Link } from "@remix-run/react"; + export default function () { + return <>

B

Go to C + } + `, + + "app/routes/replace.c.tsx": js` + import { replace } from "@remix-run/node"; + export const loader = () => replace("/replace/d"); + export default function () { + return

C

+ } + `, + + "app/routes/replace.d.tsx": js` + export default function () { + return

D

+ } + `, }, }); @@ -143,6 +171,18 @@ test.describe("redirects", () => { // Hard reload resets client side react state expect(await app.getHtml("button")).toMatch("Count:0"); }); + + test("supports replace redirects within the app", async ({ page }) => { + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/replace/a", true); + await page.waitForSelector("#a"); // [/a] + await app.clickLink("/replace/b"); + await page.waitForSelector("#b"); // [/a, /b] + await app.clickLink("/replace/c"); + await page.waitForSelector("#d"); // [/a, /d] + await page.goBack(); + await page.waitForSelector("#a"); // [/a] + }); }); // Duplicate suite of the tests above running with single fetch enabled @@ -243,6 +283,34 @@ test.describe("single fetch", () => { return

Hello B!

} `, + + "app/routes/replace.a.tsx": js` + import { Link } from "@remix-run/react"; + export default function () { + return <>

A

Go to B; + } + `, + + "app/routes/replace.b.tsx": js` + import { Link } from "@remix-run/react"; + export default function () { + return <>

B

Go to C + } + `, + + "app/routes/replace.c.tsx": js` + import { replace } from "@remix-run/node"; + export const loader = () => replace("/replace/d"); + export default function () { + return

C

+ } + `, + + "app/routes/replace.d.tsx": js` + export default function () { + return

D

+ } + `, }, }); @@ -290,5 +358,17 @@ test.describe("single fetch", () => { // Hard reload resets client side react state expect(await app.getHtml("button")).toMatch("Count:0"); }); + + test("supports replace redirects within the app", async ({ page }) => { + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/replace/a", true); + await page.waitForSelector("#a"); // [/a] + await app.clickLink("/replace/b"); + await page.waitForSelector("#b"); // [/a, /b] + await app.clickLink("/replace/c"); + await page.waitForSelector("#d"); // [/a, /d] + await page.goBack(); + await page.waitForSelector("#a"); // [/a] + }); }); }); diff --git a/integration/single-fetch-test.ts b/integration/single-fetch-test.ts index 67d2189e205..7655d09d9eb 100644 --- a/integration/single-fetch-test.ts +++ b/integration/single-fetch-test.ts @@ -1009,6 +1009,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }, }); @@ -1148,6 +1149,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }, }); @@ -1280,6 +1282,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }, }); @@ -1329,6 +1332,62 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, + revalidate: false, + }, + }); + expect(status).toBe(202); + + let appFixture = await createAppFixture(fixture); + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/"); + await app.clickLink("/data"); + await page.waitForSelector("#target"); + expect(await app.getHtml("#target")).toContain("Target"); + }); + + test("processes thrown loader replace redirects via Response", async ({ + page, + }) => { + let fixture = await createFixture({ + config: { + future: { + unstable_singleFetch: true, + }, + }, + files: { + ...files, + "app/routes/data.tsx": js` + import { replace } from '@remix-run/node'; + export function loader() { + throw replace('/target'); + } + export default function Component() { + return null + } + `, + "app/routes/target.tsx": js` + export default function Component() { + return

Target

+ } + `, + }, + }); + + console.error = () => {}; + + let res = await fixture.requestDocument("/data"); + expect(res.status).toBe(302); + expect(res.headers.get("Location")).toBe("/target"); + expect(await res.text()).toBe(""); + + let { status, data } = await fixture.requestSingleFetchData("/data.data"); + expect(data).toEqual({ + [SingleFetchRedirectSymbol]: { + status: 302, + redirect: "/target", + reload: false, + replace: true, revalidate: false, }, }); @@ -1393,6 +1452,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }); expect(status).toBe(202); @@ -1551,6 +1611,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }); expect(status).toBe(202); @@ -1702,6 +1763,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }); expect(status).toBe(202); @@ -1759,6 +1821,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }); expect(status).toBe(202); @@ -1858,6 +1921,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }, }); @@ -1960,6 +2024,7 @@ test.describe("single-fetch", () => { status: 302, redirect: "/target", reload: false, + replace: false, revalidate: false, }); expect(status).toBe(202); diff --git a/packages/remix-cloudflare/index.ts b/packages/remix-cloudflare/index.ts index a21c55b7516..22b878fd7f3 100644 --- a/packages/remix-cloudflare/index.ts +++ b/packages/remix-cloudflare/index.ts @@ -23,6 +23,7 @@ export { MaxPartSizeExceededError, redirect, redirectDocument, + replace, unstable_composeUploadHandlers, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData, diff --git a/packages/remix-deno/index.ts b/packages/remix-deno/index.ts index 97fccb83d79..5652d74ac06 100644 --- a/packages/remix-deno/index.ts +++ b/packages/remix-deno/index.ts @@ -24,6 +24,7 @@ export { MaxPartSizeExceededError, redirect, redirectDocument, + replace, unstable_composeUploadHandlers, unstable_createMemoryUploadHandler, unstable_defineAction, diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 26f81834309..3aa01012e73 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -32,7 +32,7 @@ "@mdx-js/mdx": "^2.3.0", "@npmcli/package-json": "^4.0.1", "@remix-run/node": "workspace:*", - "@remix-run/router": "1.18.0", + "@remix-run/router": "0.0.0-experimental-cffa549a1", "@remix-run/server-runtime": "workspace:*", "@types/mdx": "^2.0.5", "@vanilla-extract/integration": "^6.2.0", diff --git a/packages/remix-node/index.ts b/packages/remix-node/index.ts index eaf64599f3c..262b1a67446 100644 --- a/packages/remix-node/index.ts +++ b/packages/remix-node/index.ts @@ -35,6 +35,7 @@ export { MaxPartSizeExceededError, redirect, redirectDocument, + replace, unstable_composeUploadHandlers, unstable_createMemoryUploadHandler, unstable_parseMultipartFormData, diff --git a/packages/remix-react/index.tsx b/packages/remix-react/index.tsx index 0211ee04297..5d1dda5bcb8 100644 --- a/packages/remix-react/index.tsx +++ b/packages/remix-react/index.tsx @@ -65,6 +65,7 @@ export { json, redirect, redirectDocument, + replace, } from "@remix-run/server-runtime"; export type { RemixBrowserProps } from "./browser"; diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index b15bcaf608e..1baa7a6c2f1 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -19,10 +19,10 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "1.18.0", + "@remix-run/router": "0.0.0-experimental-cffa549a1", "@remix-run/server-runtime": "workspace:*", - "react-router": "6.25.0", - "react-router-dom": "6.25.0", + "react-router": "0.0.0-experimental-cffa549a1", + "react-router-dom": "0.0.0-experimental-cffa549a1", "turbo-stream": "2.2.0" }, "devDependencies": { diff --git a/packages/remix-react/routes.tsx b/packages/remix-react/routes.tsx index bff888a6f26..0cd09619129 100644 --- a/packages/remix-react/routes.tsx +++ b/packages/remix-react/routes.tsx @@ -604,6 +604,10 @@ function getRedirect(response: Response): Response { if (reloadDocument) { headers["X-Remix-Reload-Document"] = reloadDocument; } + let replace = response.headers.get("X-Remix-Replace"); + if (replace) { + headers["X-Remix-Replace"] = replace; + } return redirect(url, { status, headers }); } diff --git a/packages/remix-react/single-fetch.tsx b/packages/remix-react/single-fetch.tsx index 1543dab05cf..e6c156efa95 100644 --- a/packages/remix-react/single-fetch.tsx +++ b/packages/remix-react/single-fetch.tsx @@ -399,6 +399,9 @@ function unwrapSingleFetchResult(result: SingleFetchResult, routeId: string) { if (result.reload) { headers["X-Remix-Reload-Document"] = "yes"; } + if (result.replace) { + headers["X-Remix-Replace"] = "yes"; + } return redirect(result.redirect, { status: result.status, headers }); } else if ("data" in result) { return result.data; diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index 7a4d4cf9c14..c1fbfd564b2 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -4,7 +4,7 @@ export { composeUploadHandlers as unstable_composeUploadHandlers, parseMultipartFormData as unstable_parseMultipartFormData, } from "./formData"; -export { defer, json, redirect, redirectDocument } from "./responses"; +export { defer, json, redirect, redirectDocument, replace } from "./responses"; export { SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 0e5634c1f82..148fd0f0460 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -19,7 +19,7 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "1.18.0", + "@remix-run/router": "0.0.0-experimental-cffa549a1", "@types/cookie": "^0.6.0", "@web3-storage/multipart-parser": "^1.0.0", "cookie": "^0.6.0", diff --git a/packages/remix-server-runtime/responses.ts b/packages/remix-server-runtime/responses.ts index 32a609cd5cb..57b13d7e680 100644 --- a/packages/remix-server-runtime/responses.ts +++ b/packages/remix-server-runtime/responses.ts @@ -2,6 +2,7 @@ import { defer as routerDefer, json as routerJson, redirect as routerRedirect, + replace as routerReplace, redirectDocument as routerRedirectDocument, type UNSAFE_DeferredData as DeferredData, type TrackedPromise, @@ -70,6 +71,16 @@ export const redirect: RedirectFunction = (url, init = 302) => { return routerRedirect(url, init) as TypedResponse; }; +/** + * A redirect response. Sets the status code and the `Location` header. + * Defaults to "302 Found". + * + * @see https://remix.run/utils/redirect + */ +export const replace: RedirectFunction = (url, init = 302) => { + return routerReplace(url, init) as TypedResponse; +}; + /** * A redirect response that will force a document reload to the new location. * Sets the status code and the `Location` header. diff --git a/packages/remix-server-runtime/single-fetch.ts b/packages/remix-server-runtime/single-fetch.ts index 4c31135c573..9fba362d23d 100644 --- a/packages/remix-server-runtime/single-fetch.ts +++ b/packages/remix-server-runtime/single-fetch.ts @@ -27,6 +27,7 @@ type SingleFetchRedirectResult = { status: number; revalidate: boolean; reload: boolean; + replace: boolean; }; export type SingleFetchResult = | { data: unknown } @@ -464,6 +465,7 @@ export function getSingleFetchRedirect( // TODO(v3): Consider removing or making this official public API headers.has("X-Remix-Revalidate") || headers.has("Set-Cookie"), reload: headers.has("X-Remix-Reload-Document"), + replace: headers.has("X-Remix-Replace"), }; } diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index bbdff38fb78..cfab24a48fd 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -21,8 +21,8 @@ "dependencies": { "@remix-run/node": "workspace:*", "@remix-run/react": "workspace:*", - "@remix-run/router": "1.18.0", - "react-router-dom": "6.25.0" + "@remix-run/router": "0.0.0-experimental-cffa549a1", + "react-router-dom": "0.0.0-experimental-cffa549a1" }, "devDependencies": { "@remix-run/server-runtime": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c752534cdc..78decb38b4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -323,8 +323,8 @@ importers: specifier: workspace:* version: link:../packages/remix-node '@remix-run/router': - specifier: 1.18.0 - version: 1.18.0 + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1 '@remix-run/server-runtime': specifier: workspace:* version: link:../packages/remix-server-runtime @@ -871,8 +871,8 @@ importers: specifier: ^2.10.3 version: link:../remix-react '@remix-run/router': - specifier: 1.18.0 - version: 1.18.0 + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime @@ -1217,17 +1217,17 @@ importers: packages/remix-react: dependencies: '@remix-run/router': - specifier: 1.18.0 - version: 1.18.0 + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime react-router: - specifier: 6.25.0 - version: 6.25.0(react@18.2.0) + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1(react@18.2.0) react-router-dom: - specifier: 6.25.0 - version: 6.25.0(react-dom@18.2.0)(react@18.2.0) + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1(react-dom@18.2.0)(react@18.2.0) turbo-stream: specifier: 2.2.0 version: 2.2.0 @@ -1303,8 +1303,8 @@ importers: packages/remix-server-runtime: dependencies: '@remix-run/router': - specifier: 1.18.0 - version: 1.18.0 + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1 '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -1340,11 +1340,11 @@ importers: specifier: workspace:* version: link:../remix-react '@remix-run/router': - specifier: 1.18.0 - version: 1.18.0 + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1 react-router-dom: - specifier: 6.25.0 - version: 6.25.0(react-dom@18.2.0)(react@18.2.0) + specifier: 0.0.0-experimental-cffa549a1 + version: 0.0.0-experimental-cffa549a1(react-dom@18.2.0)(react@18.2.0) devDependencies: '@remix-run/server-runtime': specifier: workspace:* @@ -4201,8 +4201,8 @@ packages: - encoding dev: false - /@remix-run/router@1.18.0: - resolution: {integrity: sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==} + /@remix-run/router@0.0.0-experimental-cffa549a1: + resolution: {integrity: sha512-Pn7hkGb4NL91+wMKidAvVUxLjjWeidhBe66rfQG04BDQHoCsBvncM54KtymGprCdjM1ki06c9kcNeR3fz9rDsA==} engines: {node: '>=14.0.0'} dev: false @@ -12786,26 +12786,26 @@ packages: engines: {node: '>=0.10.0'} dev: false - /react-router-dom@6.25.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-BhcczgDWWgvGZxjDDGuGHrA8HrsSudilqTaRSBYLWDayvo1ClchNIDVt5rldqp6e7Dro5dEFx9Mzc+r292lN0w==} + /react-router-dom@0.0.0-experimental-cffa549a1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-qnObsw+nV5pgoObJ6e+PHG8pltAvpeuqtHQX/Z8VtjQTPcXhLhXysvaE2JlQGxUNnE7OnJCLLbtk2722UvK1bQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.18.0 + '@remix-run/router': 0.0.0-experimental-cffa549a1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.25.0(react@18.2.0) + react-router: 0.0.0-experimental-cffa549a1(react@18.2.0) dev: false - /react-router@6.25.0(react@18.2.0): - resolution: {integrity: sha512-bziKjCcDbcxgWS9WlWFcQIVZ2vJHnCP6DGpQDT0l+0PFDasfJKgzf9CM22eTyhFsZkjk8ApCdKjJwKtzqH80jQ==} + /react-router@0.0.0-experimental-cffa549a1(react@18.2.0): + resolution: {integrity: sha512-KAdzysntJa81nnnXkm06YowOjt62hNbLph+IH7CLltLFKKdq420fdSUxZ79olJpgWEKG9fjeqLr4X/pJCEyUrg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.18.0 + '@remix-run/router': 0.0.0-experimental-cffa549a1 react: 18.2.0 dev: false From cfc0c6f14f6934bf9806ea0cd96e61dd51c2e784 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 24 Jul 2024 16:52:48 -0400 Subject: [PATCH 25/30] Change hydration check from URL to matches (#9695) --- .changeset/tender-elephants-kneel.md | 6 +++ .../remix-react/__tests__/components-test.tsx | 2 +- packages/remix-react/browser.tsx | 54 ++++++++++--------- packages/remix-server-runtime/server.ts | 4 +- .../remix-server-runtime/serverHandoff.ts | 2 +- 5 files changed, 40 insertions(+), 28 deletions(-) create mode 100644 .changeset/tender-elephants-kneel.md diff --git a/.changeset/tender-elephants-kneel.md b/.changeset/tender-elephants-kneel.md new file mode 100644 index 00000000000..9d789d99b69 --- /dev/null +++ b/.changeset/tender-elephants-kneel.md @@ -0,0 +1,6 @@ +--- +"@remix-run/react": patch +"@remix-run/server-runtime": patch +--- + +- Change initial hydration route mismatch from a URL check to a matches check to be resistant to URL inconsistenceis diff --git a/packages/remix-react/__tests__/components-test.tsx b/packages/remix-react/__tests__/components-test.tsx index f0a30a3a1b1..0f3c353ba3d 100644 --- a/packages/remix-react/__tests__/components-test.tsx +++ b/packages/remix-react/__tests__/components-test.tsx @@ -293,7 +293,7 @@ describe("", () => { describe("", () => { it("handles empty default export objects from the compiler", () => { window.__remixContext = { - url: "/", + ssrMatches: ["root", "empty"], state: { loaderData: {}, }, diff --git a/packages/remix-react/browser.tsx b/packages/remix-react/browser.tsx index c0014b1c1e1..f0394dbe2ac 100644 --- a/packages/remix-react/browser.tsx +++ b/packages/remix-react/browser.tsx @@ -25,7 +25,7 @@ import { initFogOfWar, useFogOFWarDiscovery } from "./fog-of-war"; /* eslint-disable prefer-let/prefer-let */ declare global { var __remixContext: { - url: string; + ssrMatches: string[]; basename?: string; state: HydrationState; criticalCss?: string; @@ -194,29 +194,6 @@ if (import.meta && import.meta.hot) { */ export function RemixBrowser(_props: RemixBrowserProps): ReactElement { if (!router) { - // Hard reload if the path we tried to load is not the current path. - // This is usually the result of 2 rapid back/forward clicks from an - // external site into a Remix app, where we initially start the load for - // one URL and while the JS chunks are loading a second forward click moves - // us to a new URL. Avoid comparing search params because of CDNs which - // can be configured to ignore certain params and only pathname is relevant - // towards determining the route matches. - let initialPathname = window.__remixContext.url; - let hydratedPathname = window.location.pathname; - if ( - initialPathname !== hydratedPathname && - !window.__remixContext.isSpaMode - ) { - let errorMsg = - `Initial URL (${initialPathname}) does not match URL at time of hydration ` + - `(${hydratedPathname}), reloading page...`; - console.error(errorMsg); - window.location.reload(); - // Get out of here so the reload can happen - don't create the router - // since it'll then kick off unnecessary route.lazy() loads - return <>; - } - // When single fetch is enabled, we need to suspend until the initial state // snapshot is decoded into window.__remixContext.state if (window.__remixContext.future.unstable_singleFetch) { @@ -270,6 +247,35 @@ export function RemixBrowser(_props: RemixBrowserProps): ReactElement { window.location, window.__remixContext.basename ); + + // Hard reload if the matches we rendered on the server aren't the matches + // we matched in the client, otherwise we'll try to hydrate without the + // right modules and throw a hydration error, which can put React into an + // infinite hydration loop when hydrating the full `` document. + // This is usually the result of 2 rapid back/forward clicks from an + // external site into a Remix app, where we initially start the load for + // one URL and while the JS chunks are loading a second forward click moves + // us to a new URL. + let ssrMatches = window.__remixContext.ssrMatches; + let hasDifferentSSRMatches = + (initialMatches || []).length !== ssrMatches.length || + !(initialMatches || []).every((m, i) => ssrMatches[i] === m.route.id); + + if (hasDifferentSSRMatches && !window.__remixContext.isSpaMode) { + let ssr = ssrMatches.join(","); + let client = (initialMatches || []).map((m) => m.route.id).join(","); + let errorMsg = + `SSR Matches (${ssr}) do not match client matches (${client}) at ` + + `time of hydration , reloading page...`; + console.error(errorMsg); + + window.location.reload(); + + // Get out of here so the reload can happen - don't create the router + // since it'll then kick off unnecessary route.lazy() loads + return <>; + } + if (initialMatches) { for (let match of initialMatches) { let routeId = match.route.id; diff --git a/packages/remix-server-runtime/server.ts b/packages/remix-server-runtime/server.ts index fd81da453b9..8fa3f85fa05 100644 --- a/packages/remix-server-runtime/server.ts +++ b/packages/remix-server-runtime/server.ts @@ -515,7 +515,7 @@ async function handleDocumentRequest( staticHandlerContext: context, criticalCss, serverHandoffString: createServerHandoffString({ - url: context.location.pathname, + ssrMatches: context.matches.map((m) => m.route.id), basename: build.basename, criticalCss, future: build.future, @@ -592,7 +592,7 @@ async function handleDocumentRequest( ...entryContext, staticHandlerContext: context, serverHandoffString: createServerHandoffString({ - url: context.location.pathname, + ssrMatches: context.matches.map((m) => m.route.id), basename: build.basename, future: build.future, isSpaMode: build.isSpaMode, diff --git a/packages/remix-server-runtime/serverHandoff.ts b/packages/remix-server-runtime/serverHandoff.ts index 7328388ac3d..124cb5e0711 100644 --- a/packages/remix-server-runtime/serverHandoff.ts +++ b/packages/remix-server-runtime/serverHandoff.ts @@ -20,7 +20,7 @@ export function createServerHandoffString(serverHandoff: { // we'd end up including duplicate info state?: ValidateShape; criticalCss?: string; - url: string; + ssrMatches: string[]; basename: string | undefined; future: FutureConfig; isSpaMode: boolean; From e171af77fe8ed12c91674c9e9f8d779f758cd2eb Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 24 Jul 2024 16:58:05 -0400 Subject: [PATCH 26/30] Trim trailing slashes from single fetch data URLs (#9792) --- .changeset/large-donkeys-remember.md | 5 +++++ packages/remix-react/single-fetch.tsx | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 .changeset/large-donkeys-remember.md diff --git a/.changeset/large-donkeys-remember.md b/.changeset/large-donkeys-remember.md new file mode 100644 index 00000000000..5499280988d --- /dev/null +++ b/.changeset/large-donkeys-remember.md @@ -0,0 +1,5 @@ +--- +"@remix-run/react": patch +--- + +Ensure single fetch calls don't include any trailing slash from the pathname (i.e., /path/.data) diff --git a/packages/remix-react/single-fetch.tsx b/packages/remix-react/single-fetch.tsx index e6c156efa95..78c2715a7ec 100644 --- a/packages/remix-react/single-fetch.tsx +++ b/packages/remix-react/single-fetch.tsx @@ -304,7 +304,13 @@ export function singleFetchUrl(reqUrl: URL | string) { typeof reqUrl === "string" ? new URL(reqUrl, window.location.origin) : reqUrl; - url.pathname = `${url.pathname === "/" ? "_root" : url.pathname}.data`; + + if (url.pathname === "/") { + url.pathname = "_root.data"; + } else { + url.pathname = `${url.pathname.replace(/\/$/, "")}.data`; + } + return url; } From b163e06f66ae3d238fe633889d08bef823868d27 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Thu, 25 Jul 2024 17:27:53 -0400 Subject: [PATCH 27/30] Remove single fetch response stub, add headers (#9769) --- .changeset/add-unstable-data.md | 9 + .changeset/remove-response-stub.md | 24 + docs/guides/single-fetch.md | 134 +- docs/utils/data.md | 41 + integration/package.json | 2 +- integration/single-fetch-test.ts | 1615 ++++------------- packages/remix-cloudflare/index.ts | 1 + packages/remix-deno/index.ts | 1 + packages/remix-dev/package.json | 2 +- packages/remix-node/index.ts | 1 + .../remix-react/__tests__/exports-test.tsx | 1 + packages/remix-react/index.tsx | 1 + packages/remix-react/package.json | 6 +- packages/remix-react/single-fetch.tsx | 22 +- packages/remix-server-runtime/data.ts | 11 - packages/remix-server-runtime/index.ts | 1 + packages/remix-server-runtime/package.json | 2 +- packages/remix-server-runtime/routeModules.ts | 5 - packages/remix-server-runtime/routes.ts | 5 - packages/remix-server-runtime/server.ts | 99 +- packages/remix-server-runtime/single-fetch.ts | 287 +-- packages/remix-testing/package.json | 4 +- pnpm-lock.yaml | 50 +- 23 files changed, 587 insertions(+), 1737 deletions(-) create mode 100644 .changeset/add-unstable-data.md create mode 100644 .changeset/remove-response-stub.md create mode 100644 docs/utils/data.md diff --git a/.changeset/add-unstable-data.md b/.changeset/add-unstable-data.md new file mode 100644 index 00000000000..f1eebbd186a --- /dev/null +++ b/.changeset/add-unstable-data.md @@ -0,0 +1,9 @@ +--- +"@remix-run/cloudflare": minor +"@remix-run/deno": minor +"@remix-run/node": minor +"@remix-run/react": minor +"@remix-run/server-runtime": minor +--- + +Add a new `unstable_data()` API for usage with Remix Single Fetch diff --git a/.changeset/remove-response-stub.md b/.changeset/remove-response-stub.md new file mode 100644 index 00000000000..09b70ccded3 --- /dev/null +++ b/.changeset/remove-response-stub.md @@ -0,0 +1,24 @@ +--- +"@remix-run/server-runtime": minor +"@remix-run/react": minor +--- + +Single Fetch: Remove `responseStub` in favor of `headers` + +* Background + * The original Single Fetch approach was based on an assumption that an eventual `middleware` implementation would require something like `ResponseStub` so users could mutate `status`/`headers` in `middleware` before/after handlers as well as during handlers + * We wanted to align how `headers` got merged between document and data requests + * So we made document requests also use `ResponseStub` and removed the usage of `headers` in Single Fetch + * The realization/alignment between Michael and Ryan on the recent [roadmap planning](https://www.youtube.com/watch?v=f5z_axCofW0) made us realize that the original assumption was incorrect + * `middleware` won't need a stub - users can just mutate the `Response` they get from `await next()` directly + * With that gone, and still wanting to align how `headers` get merged, it makes more sense to stick with the current `headers` API and apply that to Single Fetch and avoid introducing a totally new thing in `RepsonseStub` (that always felt a bit awkward to work with anyway) + +* With this change: + * You are encouraged to stop returning `Response` instances in favor of returning raw data from loaders and actions: + * ~~`return json({ data: whatever });`~~ + * `return { data: whatever };` + * In most cases, you can remove your `json()` and `defer()` calls in favor of returning raw data if they weren't setting custom `status`/`headers` + * We will be removing both `json` and `defer` in the next major version, but both _should_ still work in Single Fetch in v2 to allow for incremental adoption of the new behavior + * If you need custom `status`/`headers`: + * We've added a new `unstable_data({...}, responseInit)` utility that will let you send back `status`/`headers` alongside your raw data without having to encode it into a `Response` + * The `headers()` function will let you control header merging for both document and data requests diff --git a/docs/guides/single-fetch.md b/docs/guides/single-fetch.md index 5d8bfa4fec4..5571be0d4ec 100644 --- a/docs/guides/single-fetch.md +++ b/docs/guides/single-fetch.md @@ -6,7 +6,7 @@ title: Single Fetch This is an unstable API and will continue to change, do not adopt in production -Single fetch is a new data data loading strategy and streaming format. When you enable Single Fetch, Remix will make a single HTTP call to your server on client-side transitions, instead of multiple HTTP calls in parallel (one per loader). Additionally, Single Fetch also allows you to send down naked objects from your `loader` and `action`, such as `Date`, `Error`, `Promise`, `RegExp`, and more. +Single Fetch is a new data data loading strategy and streaming format. When you enable Single Fetch, Remix will make a single HTTP call to your server on client-side transitions, instead of multiple HTTP calls in parallel (one per loader). Additionally, Single Fetch also allows you to send down naked objects from your `loader` and `action`, such as `Date`, `Error`, `Promise`, `RegExp`, and more. ## Overview @@ -51,9 +51,9 @@ Single Fetch requires using [`undici`][undici] as your `fetch` polyfill, or usin - If you are using miniflare/cloudflare worker with your remix project, ensure your [compatibility flag][compatibility-flag] is set to `2023-03-01` or later as well. -**3. Remove document-level `headers` implementation (if you have one)** +**3. Adjust `headers` implementations (if necessary)** -The [`headers`][headers] export is not longer used when single fetch is enabled. In many cases you may have been just re-returning the headers from your loader `Response` instances to apply them to document requests, and if so, you may can likely just remove the export and those Repsonse headers will apply to document requests automatically. If you were doing more complex logic for document headers in the `headers` function, then you will need to migrate those to the new [Response Stub][responsestub] instance in your `loader` functions. +With Single Fetch enabled, there will now only be one request made on client-side navigations even when multiple loaders need to run. To handle merging headers for the handlers called, the [`headers`][headers] export will now also apply to `loader`/`action` data requests. In many cases, the logic you already have in there for document requests should be close to sufficient for your new Single Fetch data requests. **4. Add `nonce` to `` (if you are using a CSP)** @@ -76,7 +76,7 @@ There are a handful of breaking changes introduced with Single Fetch - some of w **Changes that need to be addressed up front:** - **Deprecated `fetch` polyfill**: The old `installGlobals()` polyfill doesn't work for Single Fetch, you must either use the native Node 20 `fetch` API or call `installGlobals({ nativeFetch: true })` in your custom server to get the [undici-based polyfill][undici-polyfill] -- **Deprecated `headers` export**: The [`headers`][headers] function is no longer used when Single Fetch is enabled, in favor of the new `response` stub passed to your `loader`/`action` functions +- **`headers` export applied to data requests**: The [`headers`][headers] function will now apply to both document and data requests **Changes to be aware of that you may need to handle over-time:** @@ -90,7 +90,7 @@ There are a handful of breaking changes introduced with Single Fetch - some of w ## Adding a New Route with Single Fetch -With Single Fetch enabled, you can go ahead and author routes that take advantage of the more powerful streaming format and [`response` stub][responsestub]. +With Single Fetch enabled, you can go ahead and author routes that take advantage of the more powerful streaming format. In order to get proper type inference, you first need to add `@remix-run/react/future/single-fetch.d.ts` to the end of your `tsconfig.json`'s `compilerOptions.types` array. You can read more about this in the [Type Inference section][type-inference-section]. @@ -100,22 +100,18 @@ With Single Fetch you can return the following data types from your loader: `Big // routes/blog.$slug.tsx import { unstable_defineLoader as defineLoader } from "@remix-run/node"; -export const loader = defineLoader( - async ({ params, response }) => { - const { slug } = params; +export const loader = defineLoader(async ({ params }) => { + const { slug } = params; - const comments = fetchComments(slug); - const blogData = await fetchBlogData(slug); + const comments = fetchComments(slug); + const blogData = await fetchBlogData(slug); - response.headers.set("Cache-Control", "max-age=300"); - - return { - content: blogData.content, // <- string - published: blogData.date, // <- Date - comments, // <- Promise - }; - } -); + return { + content: blogData.content, // <- string + published: blogData.date, // <- Date + comments, // <- Promise + }; +}); export default function BlogPost() { const blogData = useLoaderData(); @@ -292,64 +288,18 @@ export default function Component() { ### Headers -The [`headers`][headers] function is no longer used when Single Fetch is enabled. -Instead, your `loader`/`action` functions now receive a mutable `ResponseStub` unique to that execution: +The [`headers`][headers] function is now used on both document and data requests when Single Fetch is enabled. You should use that function to merge any headers returned from loaders executed in parallel, or to return any given `actionHeaders`. -- To alter the status of your HTTP Response, set the `status` field directly: - - `response.status = 201` -- To set the headers on your HTTP Response, use the standard [`Headers`][mdn-headers] APIs: - - `response.headers.set(name, value)` - - `response.headers.append(name, value)` - - `response.headers.delete(name)` +### Returned Responses -```ts -export const action = defineAction( - async ({ request, response }) => { - if (!loggedIn(request)) { - response.status = 401; - response.headers.append("Set-Cookie", "foo=bar"); - return { message: "Invalid Submission!" }; - } - await addItemToDb(request); - return null; - } -); -``` +With Single Fetch, you no longer need to return `Response` instances and can just return your data directly via naked object returns. Therefore, the `json`/`defer` utilities should be considered deprecated when using Single Fetch. These will remain for the duration of v2 so you don't need to remove them immediately. They will likely be removed in the next major version, so we recommend remove them incrementally between now and then. -You can also throw these response stubs to short circuit the flow of your loaders and actions: +For v2, you may still continue returning normal `Response` instances and their `status`/`headers` will take effect the same way they do on document requests (merging headers via the `headers()` function). -```tsx -export const loader = defineLoader( - ({ request, response }) => { - if (shouldRedirectToHome(request)) { - response.status = 302; - response.headers.set("Location", "/"); - throw response; - } - // ... - } -); -``` +Over time, you should start eliminating returned Responses from your loaders and actions. -Each `loader`/`action` receives its own unique `response` instance so you cannot see what other `loader`/`action` functions have set (which would be subject to race conditions). The resulting HTTP Response status and headers are determined as follows: - -- Status Code - - If all status codes are unset or have values <300, the deepest status code will be used for the HTTP response - - If any status codes are set to a value >=300, the shallowest >=300 value will be used for the HTTP Response -- Headers - - Remix tracks header operations and will replay them on a fresh `Headers` instance after all handlers have completed - - These are replayed in order - action first (if present) followed by loaders in top-down order - - `headers.set` on any child handler will overwrite values from parent handlers - - `headers.append` can be used to set the same header from both a parent and child handler - - `headers.delete` can be used to delete a value set by a parent handler, but not a value set from a child handler - -Because Single Fetch supports naked object returns, and you no longer need to return a `Response` instance to set status/headers, the `json`/`redirect`/`redirectDocument`/`defer` utilities should be considered deprecated when using Single Fetch. These will remain for the duration of v2 so you don't need to remove them immediately. They will likely be removed in the next major version, so we recommend remove them incrementally between now and then. - -These utilities will remain for the rest of Remix v2, and it's likely that in a future version they'll be available via something like [`remix-utils`][remix-utils] (or they're also very easy to re-implement yourself). - -For v2, you may still continue returning normal `Response` instances and they'll apply status codes in the same way as the `response` stub, and will apply all headers via `headers.set` - overwriting any same-named header values from parents. If you need to append a header, you will need to switch from returning a `Response` instance to using the new `response` parameter. - -To ensure you can adopt these features incrementally, our goal is that you can enable Single Fetch without changing all of your `loader`/`action` functions to leverage the `response` stub. Then over time, you can incrementally convert individual routes to leverage the new `response` stub. +- If your `loader`/`action` was returning `json`/`defer` without setting any `status`/`headers`, then you can just remove the call to `json`/`defer` and return the data directly +- If your `loader`/`action` was returning custom `status`/`headers` via `json`/`defer`, you should switch those to use the new [`unstable_data()`][data-utility] utility. ### Client Loaders @@ -434,42 +384,6 @@ The Remix v2 behavior with Single Fetch enabled is as follows: Note: It is _not_ recommended to use `defineLoader`/`defineAction` for externally-accessed resource routes that need to return specific `Response` instances. It's best to just stick with `loader`/`LoaderFunctionArgs` for these cases. -#### Response Stub and Resource Routes - -As discussed above, the `headers` export is deprecated in favor of a new [`response` stub][responsestub] passed to your `loader` and `action` functions. This is somewhat confusing in resource routes, though, because you get to return the _actual_ `Response` - there's no real need for a "stub" concept because there's no merging results from multiple loaders into a single Response: - -```tsx filename=app/routes/resource.tsx -// Using your own Response is the most straightforward approach -export async function loader() { - const data = await getData(); - return Response.json(data, { - status: 200, - headers: { - "X-Custom": "whatever", - }, - }); -} -``` - -To keep things consistent, resource route `loader`/`action` functions will still receive a `response` stub and you can use it if you need to (maybe to share code amongst non-resource route handlers): - -```tsx filename=app/routes/resource.tsx -// But you can still set values on the response stub -export async function loader({ - response, -}: LoaderFunctionArgs) { - const data = await getData(); - response?.status = 200; - response?.headers.set("X-Custom", "whatever"); - return Response.json(data); -} -``` - -It's best to try to avoid using the `response` stub _and also_ returning a `Response` with custom status/headers, but if you do, the following logic will apply": - -- The `Response` instance status will take priority over any `response` stub status -- Headers operations on the `response` stub `headers` will be re-played on the returned `Response` headers instance - ## Additional Details ### Streaming Data Format @@ -557,16 +471,13 @@ Revalidation is handled via a `?_routes` query string parameter on the single fe [hydrateroot]: https://react.dev/reference/react-dom/client/hydrateRoot [starttransition]: https://react.dev/reference/react/startTransition [headers]: ../route/headers -[mdn-headers]: https://developer.mozilla.org/en-US/docs/Web/API/Headers [resource-routes]: ../guides/resource-routes [returning-response]: ../route/loader.md#returning-response-instances -[responsestub]: #headers [streaming-format]: #streaming-data-format [undici-polyfill]: https://github.com/remix-run/remix/blob/main/CHANGELOG.md#undici [undici]: https://github.com/nodejs/undici [csp]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src [csp-nonce]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources -[remix-utils]: https://github.com/sergiodxa/remix-utils [merging-remix-and-rr]: https://remix.run/blog/merging-remix-and-react-router [migration-guide]: #migrating-a-route-with-single-fetch [breaking-changes]: #breaking-changes @@ -574,3 +485,4 @@ Revalidation is handled via a `?_routes` query string parameter on the single fe [start]: #enabling-single-fetch [type-inference-section]: #type-inference [compatibility-flag]: https://developers.cloudflare.com/workers/configuration/compatibility-dates +[data-utility]: ../utils/data diff --git a/docs/utils/data.md b/docs/utils/data.md new file mode 100644 index 00000000000..c7872a64372 --- /dev/null +++ b/docs/utils/data.md @@ -0,0 +1,41 @@ +--- +title: unstable_data +toc: false +--- + +# `unstable_data` + +This is a utility for use with [Single Fetch][single-fetch] to return raw data accompanied with a status code or custom response headers. This avoids the need to serialize your data into a `Response` instance to provide custom status/headers. This is generally a replacement for `loader`/`action` functions that used [`json`][json] or [`defer`][defer] prior to Single Fetch. + +```tsx +import { unstable_data as data } from "@remix-run/node"; // or cloudflare/deno + +export const loader = async () => { + // So you can write this: + return data( + { not: "coffee" }, + { + status: 418, + headers: { + "Cache-Control": "no-store", + }, + } + ); +}; +``` + +You should _not_ be using this function if you don't need to return custom status/headers - in that case, just return the data directly: + +```tsx +export const loader = async () => { + // ❌ Bad + return data({ not: "coffee" }); + + // ✅ Good + return { not: "coffee" }; +}; +``` + +[single-fetch]: ../guides/single-fetch +[json]: ./json +[defer]: ./defer diff --git a/integration/package.json b/integration/package.json index db21212335a..be111b12c70 100644 --- a/integration/package.json +++ b/integration/package.json @@ -14,7 +14,7 @@ "@remix-run/dev": "workspace:*", "@remix-run/express": "workspace:*", "@remix-run/node": "workspace:*", - "@remix-run/router": "0.0.0-experimental-cffa549a1", + "@remix-run/router": "0.0.0-experimental-9ffbba722", "@remix-run/server-runtime": "workspace:*", "@types/express": "^4.17.9", "@vanilla-extract/css": "^1.10.0", diff --git a/integration/single-fetch-test.ts b/integration/single-fetch-test.ts index 7655d09d9eb..e383ff812ab 100644 --- a/integration/single-fetch-test.ts +++ b/integration/single-fetch-test.ts @@ -15,6 +15,16 @@ const files = { "app/root.tsx": js` import { Form, Link, Links, Meta, Outlet, Scripts } from "@remix-run/react"; + export function headers ({ actionHeaders, loaderHeaders, errorHeaders }) { + if (errorHeaders) { + return errorHeaders; + } else if ([...actionHeaders].length > 0) { + return actionHeaders; + } else { + return loaderHeaders; + } + } + export function loader() { return { message: "ROOT", @@ -84,6 +94,48 @@ const files = { ) } `, + + "app/routes/data-with-response.tsx": js` + import { useActionData, useLoaderData, unstable_data as data } from "@remix-run/react"; + + export function headers ({ actionHeaders, loaderHeaders, errorHeaders }) { + if ([...actionHeaders].length > 0) { + return actionHeaders; + } else { + return loaderHeaders; + } + } + + export async function action({ request }) { + let formData = await request.formData(); + return data({ + key: formData.get('key'), + }, { status: 201, headers: { 'X-Action': 'yes' }}); + } + + export function loader({ request }) { + if (new URL(request.url).searchParams.has("error")) { + throw new Error("Loader Error"); + } + return data({ + message: "DATA", + date: new Date("${ISO_DATE}"), + }, { status: 206, headers: { 'X-Loader': 'yes' }}); + } + + export default function DataWithResponse() { + let data = useLoaderData(); + let actionData = useActionData(); + return ( + <> +

Data

+

{data.message}

+

{data.date.toISOString()}

+ {actionData ?

{actionData.key}

: null} + + ) + } + `, }; test.describe("single-fetch", () => { @@ -152,8 +204,6 @@ test.describe("single-fetch", () => { ServerMode.Development ); - console.error = () => {}; - let res = await fixture.requestSingleFetchData("/data.data?error=true"); expect(res.data).toEqual({ root: { @@ -192,6 +242,57 @@ test.describe("single-fetch", () => { }); }); + test("loads proper data (via unstable_data) on single fetch loader requests", async () => { + let fixture = await createFixture({ + config: { + future: { + unstable_singleFetch: true, + }, + }, + files, + }); + let res = await fixture.requestSingleFetchData("/data-with-response.data"); + expect(res.status).toEqual(206); + expect(res.headers.get("X-Loader")).toEqual("yes"); + expect(res.data).toEqual({ + root: { + data: { + message: "ROOT", + }, + }, + "routes/data-with-response": { + data: { + message: "DATA", + date: new Date(ISO_DATE), + }, + }, + }); + }); + + test("loads proper data (via unstable_data) on single fetch action requests", async () => { + let fixture = await createFixture({ + config: { + future: { + unstable_singleFetch: true, + }, + }, + files, + }); + let postBody = new URLSearchParams(); + postBody.set("key", "value"); + let res = await fixture.requestSingleFetchData("/data-with-response.data", { + method: "post", + body: postBody, + }); + expect(res.status).toEqual(201); + expect(res.headers.get("X-Action")).toEqual("yes"); + expect(res.data).toEqual({ + data: { + key: "value", + }, + }); + }); + test("loads proper data on document request", async ({ page }) => { let fixture = await createFixture({ config: { @@ -335,23 +436,19 @@ test.describe("single-fetch", () => { "app/routes/action.tsx": js` import { Form, Link, useActionData, useLoaderData, useNavigation } from '@remix-run/react'; - export async function action({ request, response }) { + export async function action({ request }) { let fd = await request.formData(); if (fd.get('throw') === "5xx") { - response.status = 500; - throw new Error("Thrown 500"); + throw new Response("Thrown 500", { status: 500 }); } if (fd.get('throw') === "4xx") { - response.status = 400; - throw new Error("Thrown 400"); + throw new Response("Thrown 400", { status: 400 }); } if (fd.get('return') === "5xx") { - response.status = 500; - return "Returned 500"; + return new Response("Returned 500", { status: 500 }); } if (fd.get('return') === "4xx") { - response.status = 400; - return "Returned 400"; + return new Response("Returned 400", { status: 400 }); } return null; } @@ -427,6 +524,107 @@ test.describe("single-fetch", () => { expect(urls).toEqual([]); }); + test("does not revalidate on 4xx/5xx action responses (via unstable_data)", async ({ + page, + }) => { + let fixture = await createFixture({ + config: { + future: { + unstable_singleFetch: true, + }, + }, + files: { + ...files, + "app/routes/action.tsx": js` + import { Form, Link, useActionData, useLoaderData, useNavigation, unstable_data } from '@remix-run/react'; + + export async function action({ request }) { + let fd = await request.formData(); + if (fd.get('throw') === "5xx") { + throw unstable_data("Thrown 500", { status: 500 }); + } + if (fd.get('throw') === "4xx") { + throw unstable_data("Thrown 400", { status: 400 }); + } + if (fd.get('return') === "5xx") { + return unstable_data("Returned 500", { status: 500 }); + } + if (fd.get('return') === "4xx") { + return unstable_data("Returned 400", { status: 400 }); + } + return null; + } + + let count = 0; + export function loader() { + return { count: ++count }; + } + + export default function Comp() { + let navigation = useNavigation(); + let data = useLoaderData(); + return ( +
+ + + + +

{data.count}

+ {navigation.state === "idle" ?

idle

: null} +
+ ); + } + + export function ErrorBoundary() { + return ( +
+

Error

+ Back +
+ ); + } + `, + }, + }); + + let urls: string[] = []; + page.on("request", (req) => { + if (req.method() === "GET" && req.url().includes(".data")) { + urls.push(req.url()); + } + }); + + console.error = () => {}; + + let appFixture = await createAppFixture(fixture); + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/action"); + expect(await app.getHtml("#data")).toContain("1"); + expect(urls).toEqual([]); + + await page.click('button[name="return"][value="5xx"]'); + await page.waitForSelector("#idle"); + expect(await app.getHtml("#data")).toContain("1"); + expect(urls).toEqual([]); + + await page.click('button[name="return"][value="4xx"]'); + await page.waitForSelector("#idle"); + expect(await app.getHtml("#data")).toContain("1"); + expect(urls).toEqual([]); + + await page.click('button[name="throw"][value="5xx"]'); + await page.waitForSelector("#error"); + expect(urls).toEqual([]); + + await app.clickLink("/action"); + await page.waitForSelector("#data"); + expect(await app.getHtml("#data")).toContain("2"); + urls = []; + + await page.click('button[name="throw"][value="4xx"]'); + await page.waitForSelector("#error"); + expect(urls).toEqual([]); + }); test("returns headers correctly for singular loader and action calls", async () => { let fixture = await createFixture({ config: { @@ -437,22 +635,28 @@ test.describe("single-fetch", () => { files: { ...files, "app/routes/headers.tsx": js` - export function action({ request, response }) { + export function headers ({ actionHeaders, loaderHeaders, errorHeaders }) { + if (errorHeaders) { + return errorHeaders; + } else if ([...actionHeaders].length > 0) { + return actionHeaders; + } else { + return loaderHeaders; + } + } + + export function action({ request }) { if (new URL(request.url).searchParams.has("error")) { - response.headers.set("x-action-error", "true"); - throw response; + throw new Response(null, { headers: { "x-action-error": "true" } }); } - response.headers.set("x-action", "true"); - return null; + return new Response(null, { headers: { "x-action": "true" } }); } - export function loader({ request, response }) { + export function loader({ request }) { if (new URL(request.url).searchParams.has("error")) { - response.headers.set("x-loader-error", "true"); - throw response; + throw new Response(null, { headers: { "x-loader-error": "true" } }); } - response.headers.set("x-loader", "true"); - return null; + return new Response(null, { headers: { "x-loader": "true" } }); } export default function Comp() { @@ -501,7 +705,7 @@ test.describe("single-fetch", () => { expect(dataResponse.headers.get("x-action-error")).toEqual("true"); }); - test("merges headers from nested routes", async () => { + test("merges headers from nested routes when raw Responses are returned", async () => { let fixture = await createFixture({ config: { future: { @@ -511,13 +715,15 @@ test.describe("single-fetch", () => { files: { ...files, "app/routes/a.tsx": js` - export function loader({ request, response }) { - response.headers.set('x-one', 'a set'); - response.headers.append('x-one', 'a append'); - response.headers.set('x-two', 'a set'); - response.headers.append('x-three', 'a append'); - response.headers.set('x-four', 'a set'); - return null; + export function headers({ loaderHeaders }) { + return loaderHeaders; + } + + export function loader({ request }) { + let headers = new Headers(); + headers.set('x-one', 'a set'); + headers.set('x-two', 'a set'); + return new Response(null, { headers }); } export default function Comp() { @@ -525,35 +731,30 @@ test.describe("single-fetch", () => { } `, "app/routes/a.b.tsx": js` - export function loader({ request, response }) { - response.headers.set('x-one', 'b set'); - response.headers.append('x-one', 'b append'); - response.headers.set('x-two', 'b set'); - response.headers.append('x-three', 'b append'); - response.headers.delete('x-four'); - return null; + export function headers({ actionHeaders, loaderHeaders, parentHeaders }) { + let h = new Headers(); + for (let [name, value] of parentHeaders) { + h.set(name, value); + } + for (let [name, value] of loaderHeaders) { + h.set(name, value); + } + for (let [name, value] of actionHeaders) { + h.set(name, value); + } + return h; } - export default function Comp() { - return null; - } - `, - "app/routes/a.b.c.tsx": js` - export function action({ request, response }) { - response.headers.set('x-one', 'c action set'); - response.headers.append('x-one', 'c action append'); - response.headers.set('x-two', 'c action set'); - response.headers.append('x-three', 'c action append'); - response.headers.set('x-four', 'c action set'); - return null; + export function action({ request }) { + let headers = new Headers(); + headers.set('x-two', 'b action set'); + return new Response(null, { headers }); } - export function loader({ request, response }) { - response.headers.set('x-one', 'c set'); - response.headers.append('x-one', 'c append'); - response.headers.set('x-two', 'c set'); - response.headers.append('x-three', 'c append'); - return null; + export function loader({ request }) { + let headers = new Headers(); + headers.set('x-two', 'b set'); + return new Response(null, { headers }); } export default function Comp() { @@ -573,94 +774,39 @@ test.describe("single-fetch", () => { > >; res = await fixture.requestDocument("/a"); - expect(res.headers.get("x-one")).toEqual("a set, a append"); + expect(res.headers.get("x-one")).toEqual("a set"); expect(res.headers.get("x-two")).toEqual("a set"); - expect(res.headers.get("x-three")).toEqual("a append"); - expect(res.headers.get("x-four")).toEqual("a set"); res = await fixture.requestSingleFetchData("/a.data"); - expect(res.headers.get("x-one")).toEqual("a set, a append"); + expect(res.headers.get("x-one")).toEqual("a set"); expect(res.headers.get("x-two")).toEqual("a set"); - expect(res.headers.get("x-three")).toEqual("a append"); - expect(res.headers.get("x-four")).toEqual("a set"); res = await fixture.requestDocument("/a/b"); - expect(res.headers.get("x-one")).toEqual("b set, b append"); + expect(res.headers.get("x-one")).toEqual("a set"); expect(res.headers.get("x-two")).toEqual("b set"); - expect(res.headers.get("x-three")).toEqual("a append, b append"); - expect(res.headers.get("x-four")).toEqual(null); res = await fixture.requestSingleFetchData("/a/b.data"); - expect(res.headers.get("x-one")).toEqual("b set, b append"); - expect(res.headers.get("x-two")).toEqual("b set"); - expect(res.headers.get("x-three")).toEqual("a append, b append"); - expect(res.headers.get("x-four")).toEqual(null); - - res = await fixture.requestDocument("/a/b/c"); - expect(res.headers.get("x-one")).toEqual("c set, c append"); - expect(res.headers.get("x-two")).toEqual("c set"); - expect(res.headers.get("x-three")).toEqual("a append, b append, c append"); - expect(res.headers.get("x-four")).toEqual(null); - - res = await fixture.requestSingleFetchData("/a/b/c.data"); - expect(res.headers.get("x-one")).toEqual("c set, c append"); - expect(res.headers.get("x-two")).toEqual("c set"); - expect(res.headers.get("x-three")).toEqual("a append, b append, c append"); - expect(res.headers.get("x-four")).toEqual(null); - - // Fine-grained revalidation - res = await fixture.requestDocument("/a/b/c.data?_routes=routes%2Fa"); - expect(res.headers.get("x-one")).toEqual("a set, a append"); - expect(res.headers.get("x-two")).toEqual("a set"); - expect(res.headers.get("x-three")).toEqual("a append"); - expect(res.headers.get("x-four")).toEqual("a set"); - - res = await fixture.requestDocument( - "/a/b.data?_routes=routes%2Fa,routes%2Fa.b" - ); - expect(res.headers.get("x-one")).toEqual("b set, b append"); + expect(res.headers.get("x-one")).toEqual("a set"); expect(res.headers.get("x-two")).toEqual("b set"); - expect(res.headers.get("x-three")).toEqual("a append, b append"); - expect(res.headers.get("x-four")).toEqual(null); - - res = await fixture.requestDocument("/a/b/c.data?_routes=routes%2Fa.b.c"); - expect(res.headers.get("x-one")).toEqual("c set, c append"); - expect(res.headers.get("x-two")).toEqual("c set"); - expect(res.headers.get("x-three")).toEqual("c append"); - expect(res.headers.get("x-four")).toEqual(null); - - res = await fixture.requestDocument( - "/a/b/c.data?_routes=routes%2Fa,routes%2Fa.b.c" - ); - expect(res.headers.get("x-one")).toEqual("c set, c append"); - expect(res.headers.get("x-two")).toEqual("c set"); - expect(res.headers.get("x-three")).toEqual("a append, c append"); - expect(res.headers.get("x-four")).toEqual("a set"); // Action only - single fetch request - res = await fixture.requestSingleFetchData("/a/b/c.data", { + res = await fixture.requestSingleFetchData("/a/b.data", { method: "post", body: null, }); - expect(res.headers.get("x-one")).toEqual("c action set, c action append"); - expect(res.headers.get("x-two")).toEqual("c action set"); - expect(res.headers.get("x-three")).toEqual("c action append"); - expect(res.headers.get("x-four")).toEqual("c action set"); + expect(res.headers.get("x-one")).toEqual(null); + expect(res.headers.get("x-two")).toEqual("b action set"); // Actions and Loaders - Document request - res = await fixture.requestDocument("/a/b/c", { + res = await fixture.requestDocument("/a/b", { method: "post", body: null, }); - expect(res.headers.get("x-one")).toEqual("c set, c append"); - expect(res.headers.get("x-two")).toEqual("c set"); - expect(res.headers.get("x-three")).toEqual( - "c action append, a append, b append, c append" - ); - expect(res.headers.get("x-four")).toEqual(null); + expect(res.headers.get("x-one")).toEqual("a set"); + expect(res.headers.get("x-two")).toEqual("b action set"); }); - test("merges status codes from nested routes", async () => { + test("merges status codes from nested routes when raw Responses are used", async () => { let fixture = await createFixture({ config: { future: { @@ -670,13 +816,12 @@ test.describe("single-fetch", () => { files: { ...files, "app/routes/a.tsx": js` - export function loader({ request, response }) { + export function loader({ request }) { if (new URL(request.url).searchParams.has("error")) { - response.status = 401 + throw new Response(null, { status: 401 }); } else { - response.status = 201 + return new Response(null, { status: 201 }); } - return null; } export default function Comp() { @@ -684,9 +829,8 @@ test.describe("single-fetch", () => { } `, "app/routes/a.b.tsx": js` - export function loader({ request, response }) { - response.status = 202 - return null; + export function loader({ request }) { + return new Response(null, { status: 202 }); } export default function Comp() { @@ -694,14 +838,12 @@ test.describe("single-fetch", () => { } `, "app/routes/a.b.c.tsx": js` - export function action({ request, response }) { - response.status = 206 - return null; + export function action({ request }) { + return new Response(null, { status: 206 }); } - export function loader({ request, response }) { - response.status = 203 - return null; + export function loader({ request }) { + return new Response(null, { status: 203 }); } export default function Comp() { @@ -711,6 +853,8 @@ test.describe("single-fetch", () => { }, }); + console.error = () => {}; + // Loaders let res: Awaited< ReturnType< @@ -762,7 +906,7 @@ test.describe("single-fetch", () => { expect(res.status).toEqual(206); }); - test("merges headers from nested routes when raw Responses are returned", async () => { + test("processes thrown loader redirects via Response", async ({ page }) => { let fixture = await createFixture({ config: { future: { @@ -771,221 +915,13 @@ test.describe("single-fetch", () => { }, files: { ...files, - "app/routes/a.tsx": js` - export function loader({ request}) { - let headers = new Headers(); - headers.set('x-one', 'a set'); - headers.append('x-one', 'a append'); - headers.set('x-two', 'a set'); - headers.append('x-three', 'a append'); - headers.set('x-four', 'a set'); - return new Response(null, { headers }); + "app/routes/data.tsx": js` + import { redirect } from '@remix-run/node'; + export function loader() { + throw redirect('/target'); } - - export default function Comp() { - return null; - } - `, - "app/routes/a.b.tsx": js` - export function action({ request, response }) { - let headers = new Headers(); - headers.set('x-one', 'b action set'); - headers.append('x-one', 'b action append'); - headers.set('x-two', 'b action set'); - headers.append('x-three', 'b action append'); - headers.set('x-four', 'b action set'); - return new Response(null, { headers }); - } - - export function loader({ request, response }) { - let headers = new Headers(); - headers.set('x-one', 'b set'); - headers.append('x-one', 'b append'); - headers.set('x-two', 'b set'); - headers.append('x-three', 'b append'); - headers.delete('x-four'); - return new Response(null, { headers }); - } - - export default function Comp() { - return null; - } - `, - }, - }); - - // x-one uses both set and append - // x-two only uses set - // x-three only uses append - // x-four deletes - let res: Awaited< - ReturnType< - typeof fixture.requestDocument | typeof fixture.requestSingleFetchData - > - >; - res = await fixture.requestDocument("/a"); - expect(res.headers.get("x-one")).toEqual("a set, a append"); - expect(res.headers.get("x-two")).toEqual("a set"); - expect(res.headers.get("x-three")).toEqual("a append"); - expect(res.headers.get("x-four")).toEqual("a set"); - - res = await fixture.requestSingleFetchData("/a.data"); - expect(res.headers.get("x-one")).toEqual("a set, a append"); - expect(res.headers.get("x-two")).toEqual("a set"); - expect(res.headers.get("x-three")).toEqual("a append"); - expect(res.headers.get("x-four")).toEqual("a set"); - - res = await fixture.requestDocument("/a/b"); - expect(res.headers.get("x-one")).toEqual("b set, b append"); - expect(res.headers.get("x-two")).toEqual("b set"); - expect(res.headers.get("x-three")).toEqual("b append"); // Blows away "a append" - expect(res.headers.get("x-four")).toEqual("a set"); - - res = await fixture.requestSingleFetchData("/a/b.data"); - expect(res.headers.get("x-one")).toEqual("b set, b append"); - expect(res.headers.get("x-two")).toEqual("b set"); - expect(res.headers.get("x-three")).toEqual("b append"); // Blows away "a append" - expect(res.headers.get("x-four")).toEqual("a set"); - - // Action only - single fetch request - res = await fixture.requestSingleFetchData("/a/b.data", { - method: "post", - body: null, - }); - expect(res.headers.get("x-one")).toEqual("b action set, b action append"); - expect(res.headers.get("x-two")).toEqual("b action set"); - expect(res.headers.get("x-three")).toEqual("b action append"); - expect(res.headers.get("x-four")).toEqual("b action set"); - - // Actions and Loaders - Document request - res = await fixture.requestDocument("/a/b", { - method: "post", - body: null, - }); - expect(res.headers.get("x-one")).toEqual("b set, b append"); - expect(res.headers.get("x-two")).toEqual("b set"); - expect(res.headers.get("x-three")).toEqual("b append"); // Blows away prior appends - expect(res.headers.get("x-four")).toEqual("a set"); // Can't delete via Response - }); - - test("merges status codes from nested routes when raw Responses are used", async () => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/a.tsx": js` - export function loader({ request, response }) { - if (new URL(request.url).searchParams.has("error")) { - return new Response(null, { status: 401 }); - } else { - return new Response(null, { status: 201 }); - } - } - - export default function Comp() { - return null; - } - `, - "app/routes/a.b.tsx": js` - export function loader({ request, response }) { - return new Response(null, { status: 202 }); - } - - export default function Comp() { - return null; - } - `, - "app/routes/a.b.c.tsx": js` - export function action({ request, response }) { - return new Response(null, { status: 206 }); - } - - export function loader({ request, response }) { - return new Response(null, { status: 203 }); - } - - export default function Comp() { - return null; - } - `, - }, - }); - - // Loaders - let res: Awaited< - ReturnType< - typeof fixture.requestDocument | typeof fixture.requestSingleFetchData - > - >; - res = await fixture.requestDocument("/a"); - expect(res.status).toEqual(201); - - res = await fixture.requestSingleFetchData("/a.data"); - expect(res.status).toEqual(201); - - res = await fixture.requestDocument("/a/b"); - expect(res.status).toEqual(202); - - res = await fixture.requestSingleFetchData("/a/b.data"); - expect(res.status).toEqual(202); - - res = await fixture.requestDocument("/a/b/c"); - expect(res.status).toEqual(203); - - res = await fixture.requestSingleFetchData("/a/b/c.data"); - expect(res.status).toEqual(203); - - // Errors - res = await fixture.requestDocument("/a?error"); - expect(res.status).toEqual(401); - - res = await fixture.requestSingleFetchData("/a.data?error"); - expect(res.status).toEqual(401); - - res = await fixture.requestDocument("/a/b?error"); - expect(res.status).toEqual(401); - - res = await fixture.requestSingleFetchData("/a/b.data?error"); - expect(res.status).toEqual(401); - - // Actions - res = await fixture.requestDocument("/a/b/c", { - method: "post", - body: null, - }); - expect(res.status).toEqual(206); - - res = await fixture.requestSingleFetchData("/a/b/c.data", { - method: "post", - body: null, - }); - expect(res.status).toEqual(206); - }); - - test("processes thrown loader redirects via responseStub", async ({ - page, - }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader({ request, response }) { - response.status = 302; - response.headers.set('Location', '/target'); - throw response; - } - export default function Component() { - return null + export default function Component() { + return null } `, "app/routes/target.tsx": js` @@ -1023,94 +959,7 @@ test.describe("single-fetch", () => { expect(await app.getHtml("#target")).toContain("Target"); }); - test("processes thrown loader redirects via responseStub (resource route)", async ({ - page, - }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader({ request, response }) { - response.status = 302; - response.headers.set('Location', '/target'); - throw response; - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }); - - console.error = () => {}; - - let res = await fixture.requestDocument("/data"); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes returned loader redirects via responseStub", async ({ - page, - }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader({ request, response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return response - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }); - - let res = await fixture.requestDocument("/data"); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes loader redirects via responseStub when null is returned", async ({ - page, - }) => { + test("processes returned loader redirects via Response", async ({ page }) => { let fixture = await createFixture({ config: { future: { @@ -1121,10 +970,8 @@ test.describe("single-fetch", () => { ...files, "app/routes/data.tsx": js` import { redirect } from '@remix-run/node'; - export function loader({ request, response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return null + export function loader() { + return redirect('/target'); } export default function Component() { return null @@ -1137,7 +984,6 @@ test.describe("single-fetch", () => { `, }, }); - let res = await fixture.requestDocument("/data"); expect(res.status).toBe(302); expect(res.headers.get("Location")).toBe("/target"); @@ -1163,7 +1009,7 @@ test.describe("single-fetch", () => { expect(await app.getHtml("#target")).toContain("Target"); }); - test("processes returned loader redirects via responseStub (resource route)", async ({ + test("processes thrown loader replace redirects via Response", async ({ page, }) => { let fixture = await createFixture({ @@ -1175,11 +1021,12 @@ test.describe("single-fetch", () => { files: { ...files, "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader({ request, response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return response; + import { replace } from '@remix-run/node'; + export function loader() { + throw replace('/target'); + } + export default function Component() { + return null } `, "app/routes/target.tsx": js` @@ -1189,192 +1036,8 @@ test.describe("single-fetch", () => { `, }, }); - - let res = await fixture.requestDocument("/data"); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes loader redirects via responseStub when null is returned (resource route)", async ({ - page, - }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader({ request, response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }); - - let res = await fixture.requestDocument("/data"); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes thrown loader redirects via Response", async ({ page }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader() { - throw redirect('/target'); - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }); - - console.error = () => {}; - - let res = await fixture.requestDocument("/data"); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let { status, data } = await fixture.requestSingleFetchData("/data.data"); - expect(data).toEqual({ - [SingleFetchRedirectSymbol]: { - status: 302, - redirect: "/target", - reload: false, - replace: false, - revalidate: false, - }, - }); - expect(status).toBe(202); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes returned loader redirects via Response", async ({ page }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function loader() { - return redirect('/target'); - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }); - let res = await fixture.requestDocument("/data"); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let { status, data } = await fixture.requestSingleFetchData("/data.data"); - expect(data).toEqual({ - [SingleFetchRedirectSymbol]: { - status: 302, - redirect: "/target", - reload: false, - replace: false, - revalidate: false, - }, - }); - expect(status).toBe(202); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes thrown loader replace redirects via Response", async ({ - page, - }) => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { replace } from '@remix-run/node'; - export function loader() { - throw replace('/target'); - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }); - - console.error = () => {}; + + console.error = () => {}; let res = await fixture.requestDocument("/data"); expect(res.status).toBe(302); @@ -1389,329 +1052,14 @@ test.describe("single-fetch", () => { reload: false, replace: true, revalidate: false, - }, - }); - expect(status).toBe(202); - - let appFixture = await createAppFixture(fixture); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickLink("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes thrown action redirects via responseStub", async ({ - page, - }) => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function action({ response }) { - response.status = 302; - response.headers.set('Location', '/target'); - throw response; - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }, - ServerMode.Development - ); - - console.error = () => {}; - - let res = await fixture.requestDocument("/data", { - method: "post", - body: null, - }); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let { status, data } = await fixture.requestSingleFetchData("/data.data", { - method: "post", - body: null, - }); - expect(data).toEqual({ - status: 302, - redirect: "/target", - reload: false, - replace: false, - revalidate: false, - }); - expect(status).toBe(202); - - let appFixture = await createAppFixture(fixture, ServerMode.Development); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickSubmitButton("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes thrown action redirects via responseStub (resource route)", async ({ - page, - }) => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function action({ response }) { - response.status = 302; - response.headers.set('Location', '/target'); - throw response; - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }, - ServerMode.Development - ); - - console.error = () => {}; - - let res = await fixture.requestDocument("/data", { - method: "post", - body: null, - }); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture, ServerMode.Development); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickSubmitButton("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes returned action redirects via responseStub", async ({ - page, - }) => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function action({ response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return response - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }, - ServerMode.Development - ); - - let res = await fixture.requestDocument("/data", { - method: "post", - body: null, - }); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture, ServerMode.Development); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickSubmitButton("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes action redirects via responseStub when null is returned", async ({ - page, - }) => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function action({ response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return null - } - export default function Component() { - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }, - ServerMode.Development - ); - - let res = await fixture.requestDocument("/data", { - method: "post", - body: null, - }); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let { status, data } = await fixture.requestSingleFetchData("/data.data", { - method: "post", - body: null, - }); - expect(data).toEqual({ - status: 302, - redirect: "/target", - reload: false, - replace: false, - revalidate: false, - }); - expect(status).toBe(202); - - let appFixture = await createAppFixture(fixture, ServerMode.Development); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickSubmitButton("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes returned action redirects via responseStub (resource route)", async ({ - page, - }) => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function action({ response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return response - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }, - ServerMode.Development - ); - - let res = await fixture.requestDocument("/data", { - method: "post", - body: null, - }); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); - - let appFixture = await createAppFixture(fixture, ServerMode.Development); - let app = new PlaywrightFixture(appFixture, page); - await app.goto("/"); - await app.clickSubmitButton("/data"); - await page.waitForSelector("#target"); - expect(await app.getHtml("#target")).toContain("Target"); - }); - - test("processes returned action redirects via responseStub when null is returned (resource route)", async ({ - page, - }) => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/data.tsx": js` - import { redirect } from '@remix-run/node'; - export function action({ response }) { - response.status = 302; - response.headers.set('Location', '/target'); - return null - } - `, - "app/routes/target.tsx": js` - export default function Component() { - return

Target

- } - `, - }, - }, - ServerMode.Development - ); - - let res = await fixture.requestDocument("/data", { - method: "post", - body: null, + }, }); - expect(res.status).toBe(302); - expect(res.headers.get("Location")).toBe("/target"); - expect(await res.text()).toBe(""); + expect(status).toBe(202); - let appFixture = await createAppFixture(fixture, ServerMode.Development); + let appFixture = await createAppFixture(fixture); let app = new PlaywrightFixture(appFixture, page); await app.goto("/"); - await app.clickSubmitButton("/data"); + await app.clickLink("/data"); await page.waitForSelector("#target"); expect(await app.getHtml("#target")).toContain("Target"); }); @@ -1834,6 +1182,84 @@ test.describe("single-fetch", () => { expect(await app.getHtml("#target")).toContain("Target"); }); + test("processes thrown loader redirects (resource route)", async ({ + page, + }) => { + let fixture = await createFixture({ + config: { + future: { + unstable_singleFetch: true, + }, + }, + files: { + ...files, + "app/routes/data.tsx": js` + import { redirect } from '@remix-run/node'; + export function loader({ request }) { + throw redirect('/target'); + } + `, + "app/routes/target.tsx": js` + export default function Component() { + return

Target

+ } + `, + }, + }); + + console.error = () => {}; + + let res = await fixture.requestDocument("/data"); + expect(res.status).toBe(302); + expect(res.headers.get("Location")).toBe("/target"); + expect(await res.text()).toBe(""); + + let appFixture = await createAppFixture(fixture); + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/"); + await app.clickLink("/data"); + await page.waitForSelector("#target"); + expect(await app.getHtml("#target")).toContain("Target"); + }); + + test("processes returned loader redirects (resource route)", async ({ + page, + }) => { + let fixture = await createFixture({ + config: { + future: { + unstable_singleFetch: true, + }, + }, + files: { + ...files, + "app/routes/data.tsx": js` + import { redirect } from '@remix-run/node'; + export function loader({ request }) { + return redirect('/target'); + } + `, + "app/routes/target.tsx": js` + export default function Component() { + return

Target

+ } + `, + }, + }); + + let res = await fixture.requestDocument("/data"); + expect(res.status).toBe(302); + expect(res.headers.get("Location")).toBe("/target"); + expect(await res.text()).toBe(""); + + let appFixture = await createAppFixture(fixture); + let app = new PlaywrightFixture(appFixture, page); + await app.goto("/"); + await app.clickLink("/data"); + await page.waitForSelector("#target"); + expect(await app.getHtml("#target")).toContain("Target"); + }); + test("processes redirects from handleDataRequest (after loaders)", async ({ page, }) => { @@ -2037,7 +1463,7 @@ test.describe("single-fetch", () => { expect(await app.getHtml("#target")).toContain("Target"); }); - test("processes thrown loader errors via responseStub", async ({ page }) => { + test("processes thrown loader errors", async ({ page }) => { let fixture = await createFixture({ config: { future: { @@ -2049,10 +1475,11 @@ test.describe("single-fetch", () => { "app/routes/data.tsx": js` import { redirect } from '@remix-run/node'; import { isRouteErrorResponse, useRouteError } from '@remix-run/react'; - export function loader({ request, response }) { - response.status = 404; - response.headers.set('X-Foo', 'Bar'); - throw response; + export function headers({ errorHeaders }) { + return errorHeaders; + } + export function loader({ request }) { + throw new Response(null, { status: 404, headers: { 'X-Foo': 'Bar' } }); } export default function Component() { return null @@ -2095,10 +1522,11 @@ test.describe("single-fetch", () => { "app/routes/data.tsx": js` import { redirect } from '@remix-run/node'; import { isRouteErrorResponse, useRouteError } from '@remix-run/react'; - export function action({ request, response }) { - response.status = 404; - response.headers.set('X-Foo', 'Bar'); - throw response; + export function headers({ errorHeaders }) { + return errorHeaders; + } + export function action({ request }) { + throw new Response(null, { status: 404, headers: { 'X-Foo': 'Bar' } }); } export default function Component() { return null @@ -2171,196 +1599,6 @@ test.describe("single-fetch", () => { console.warn = oldConsoleWarn; }); - test("allows resource routes to return null using a response stub", async () => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/resource.tsx": js` - export function loader({ response }) { - response.status = 201; - response.headers.set('X-Created-Id', '1'); - return null; - } - `, - }, - }, - ServerMode.Development - ); - let res = await fixture.requestResource("/resource"); - expect(res.status).toBe(201); - expect(res.headers.get("X-Created-Id")).toBe("1"); - expect(await res.text()).toBe(""); - }); - - test("processes response stub onto resource routes returning raw data", async () => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/resource.tsx": js` - import { json } from '@remix-run/node'; - - export function loader({ response }) { - // When raw json is returned, the stub status/headers will just be used directly - response.status = 201; - response.headers.set('X-Stub', 'yes') - return { message: "RESOURCE" }; - } - `, - }, - }, - ServerMode.Development - ); - let res = await fixture.requestResource("/resource"); - expect(res.status).toBe(201); - expect(res.headers.get("X-Stub")).toBe("yes"); - expect(await res.json()).toEqual({ - message: "RESOURCE", - }); - }); - - test("processes response stub onto resource routes returning responses", async () => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/resource.tsx": js` - import { json } from '@remix-run/node'; - - export function loader({ response }) { - // This will be ignored in favor of the returned Response status - response.status = 200; - response.headers.set('X-Stub', 'yes') - // This will overwrite the returned Response header - response.headers.set('X-Set', '2') - // This will append to the returned Response header - response.headers.append('X-Append', '2') - return json({ message: "RESOURCE" }, { - // This one takes precedence - status: 201, - headers: { - 'X-Response': 'yes', - 'X-Set': '1', - 'X-Append': '1', - }, - }); - } - `, - }, - }, - ServerMode.Development - ); - let res = await fixture.requestResource("/resource"); - expect(res.status).toBe(201); - expect(res.headers.get("X-Response")).toBe("yes"); - expect(res.headers.get("X-Stub")).toBe("yes"); - expect(res.headers.get("X-Set")).toBe("2"); - expect(res.headers.get("X-Append")).toBe("1, 2"); - expect(await res.json()).toEqual({ - message: "RESOURCE", - }); - }); - - test("processes returned response stub redirects from resource route", async () => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/resource.tsx": js` - import { json } from '@remix-run/node'; - - export function loader({ response }) { - response.status = 301; - response.headers.set('Location', '/whatever') - return response; - } - `, - }, - }, - ServerMode.Development - ); - let res = await fixture.requestResource("/resource"); - expect(res.status).toBe(301); - expect(res.headers.get("Location")).toBe("/whatever"); - }); - - test("processes thrown response stub redirects from resource route", async () => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/resource.tsx": js` - import { json } from '@remix-run/node'; - - export function loader({ response }) { - response.status = 301; - response.headers.set('Location', '/whatever') - throw response; - } - `, - }, - }, - ServerMode.Development - ); - let res = await fixture.requestResource("/resource"); - expect(res.status).toBe(301); - expect(res.headers.get("Location")).toBe("/whatever"); - }); - - test("processes response stub redirects when null is returned from resource route", async () => { - let fixture = await createFixture( - { - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/resource.tsx": js` - import { json } from '@remix-run/node'; - - export function loader({ response }) { - response.status = 301; - response.headers.set('Location', '/whatever') - return null; - } - `, - }, - }, - ServerMode.Development - ); - let res = await fixture.requestResource("/resource"); - expect(res.status).toBe(301); - expect(res.headers.get("Location")).toBe("/whatever"); - }); - test("allows fetcher to hit resource route and return via turbo stream", async ({ page, }) => { @@ -2410,81 +1648,6 @@ test.describe("single-fetch", () => { ); }); - test("does not log thrown redirect response stubs via handleError", async () => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/redirect.tsx": js` - export function action({ response }) { - response.status = 301; - response.headers.set("Location", "/data"); - throw response; - } - export function loader({ response }) { - response.status = 301; - response.headers.set("Location", "/data"); - throw response; - } - export default function Component() { - return

Should not see me

; - } - `, - }, - }); - - let errorLogs = []; - console.error = (e) => errorLogs.push(e); - await fixture.requestDocument("/redirect"); - await fixture.requestSingleFetchData("/redirect.data"); - await fixture.requestSingleFetchData("/redirect.data", { - method: "post", - body: null, - }); - expect(errorLogs.length).toBe(0); - }); - - test("does not log thrown non-redirect response stubs via handleError", async () => { - let fixture = await createFixture({ - config: { - future: { - unstable_singleFetch: true, - }, - }, - files: { - ...files, - "app/routes/redirect.tsx": js` - export function action({ response }) { - response.status = 400; - throw response; - } - export function loader({ response }) { - response.status = 400; - throw response; - } - export default function Component() { - return

Should not see me

; - } - `, - }, - }); - - let errorLogs = []; - console.error = (e) => errorLogs.push(e); - await fixture.requestDocument("/redirect"); - expect(errorLogs.length).toBe(1); // ErrorBoundary render logs this - await fixture.requestSingleFetchData("/redirect.data"); - await fixture.requestSingleFetchData("/redirect.data", { - method: "post", - body: null, - }); - expect(errorLogs.length).toBe(1); - }); - test.describe("client loaders", () => { test("when no routes have client loaders", async ({ page }) => { let fixture = await createFixture( diff --git a/packages/remix-cloudflare/index.ts b/packages/remix-cloudflare/index.ts index 22b878fd7f3..996f5f6749e 100644 --- a/packages/remix-cloudflare/index.ts +++ b/packages/remix-cloudflare/index.ts @@ -12,6 +12,7 @@ export { export { createRequestHandler, createSession, + unstable_data, unstable_defineLoader, unstable_defineAction, defer, diff --git a/packages/remix-deno/index.ts b/packages/remix-deno/index.ts index 5652d74ac06..7e7cbbb2c09 100644 --- a/packages/remix-deno/index.ts +++ b/packages/remix-deno/index.ts @@ -27,6 +27,7 @@ export { replace, unstable_composeUploadHandlers, unstable_createMemoryUploadHandler, + unstable_data, unstable_defineAction, unstable_defineLoader, unstable_parseMultipartFormData, diff --git a/packages/remix-dev/package.json b/packages/remix-dev/package.json index 3aa01012e73..c3deccbf41c 100644 --- a/packages/remix-dev/package.json +++ b/packages/remix-dev/package.json @@ -32,7 +32,7 @@ "@mdx-js/mdx": "^2.3.0", "@npmcli/package-json": "^4.0.1", "@remix-run/node": "workspace:*", - "@remix-run/router": "0.0.0-experimental-cffa549a1", + "@remix-run/router": "0.0.0-experimental-9ffbba722", "@remix-run/server-runtime": "workspace:*", "@types/mdx": "^2.0.5", "@vanilla-extract/integration": "^6.2.0", diff --git a/packages/remix-node/index.ts b/packages/remix-node/index.ts index 262b1a67446..0665a313185 100644 --- a/packages/remix-node/index.ts +++ b/packages/remix-node/index.ts @@ -24,6 +24,7 @@ export { export { createRequestHandler, createSession, + unstable_data, unstable_defineLoader, unstable_defineAction, defer, diff --git a/packages/remix-react/__tests__/exports-test.tsx b/packages/remix-react/__tests__/exports-test.tsx index 3cdb38d2e9c..953b9cd0f6b 100644 --- a/packages/remix-react/__tests__/exports-test.tsx +++ b/packages/remix-react/__tests__/exports-test.tsx @@ -40,6 +40,7 @@ let modifiedExports = new Set([ "json", // types "redirect", // types "redirectDocument", // types + "replace", // types "useActionData", // types "useFetcher", // types "useLoaderData", // types diff --git a/packages/remix-react/index.tsx b/packages/remix-react/index.tsx index 5d1dda5bcb8..8d8809ca644 100644 --- a/packages/remix-react/index.tsx +++ b/packages/remix-react/index.tsx @@ -66,6 +66,7 @@ export { redirect, redirectDocument, replace, + unstable_data, } from "@remix-run/server-runtime"; export type { RemixBrowserProps } from "./browser"; diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json index 1baa7a6c2f1..a94277518ed 100644 --- a/packages/remix-react/package.json +++ b/packages/remix-react/package.json @@ -19,10 +19,10 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "0.0.0-experimental-cffa549a1", + "@remix-run/router": "0.0.0-experimental-9ffbba722", "@remix-run/server-runtime": "workspace:*", - "react-router": "0.0.0-experimental-cffa549a1", - "react-router-dom": "0.0.0-experimental-cffa549a1", + "react-router": "0.0.0-experimental-9ffbba722", + "react-router-dom": "0.0.0-experimental-9ffbba722", "turbo-stream": "2.2.0" }, "devDependencies": { diff --git a/packages/remix-react/single-fetch.tsx b/packages/remix-react/single-fetch.tsx index 78c2715a7ec..da3f35081d3 100644 --- a/packages/remix-react/single-fetch.tsx +++ b/packages/remix-react/single-fetch.tsx @@ -7,7 +7,9 @@ import type { } from "@remix-run/router"; import { UNSAFE_ErrorResponseImpl as ErrorResponseImpl, + isRouteErrorResponse, redirect, + unstable_data, } from "@remix-run/router"; import type { UNSAFE_SingleFetchResult as SingleFetchResult, @@ -23,7 +25,7 @@ import type { } from "react-router-dom"; import { decode } from "turbo-stream"; -import { createRequestInit } from "./data"; +import { createRequestInit, isResponse } from "./data"; import type { AssetsManifest, EntryContext } from "./entry"; import { escapeHtml } from "./markup"; import type { RouteModules } from "./routeModules"; @@ -163,16 +165,18 @@ function singleFetchActionStrategy( actionStatus = status; return unwrapSingleFetchResult(data as SingleFetchResult, m.route.id); }); - return { - type: "data", - result, - status: actionStatus, - }; + return { type: "data", result }; }); + + if (isResponse(result.result) || isRouteErrorResponse(result.result)) { + return result; + } + + // For non-responses, proxy along the statusCode via unstable_data() + // (most notably for skipping action error revalidation) return { - ...result, - // Proxy along the action HTTP response status for thrown errors - status: actionStatus, + type: result.type, + result: unstable_data(result.result, actionStatus), }; }) ); diff --git a/packages/remix-server-runtime/data.ts b/packages/remix-server-runtime/data.ts index bdca6350064..e4c0ffc4e6b 100644 --- a/packages/remix-server-runtime/data.ts +++ b/packages/remix-server-runtime/data.ts @@ -11,7 +11,6 @@ import type { LoaderFunction, LoaderFunctionArgs, } from "./routeModules"; -import type { ResponseStub } from "./single-fetch"; /** * An object of unknown type for route loaders and actions provided by the @@ -35,7 +34,6 @@ export async function callRouteAction({ request, routeId, singleFetch, - response, }: { request: Request; action: ActionFunction; @@ -43,15 +41,11 @@ export async function callRouteAction({ loadContext: AppLoadContext; routeId: string; singleFetch: boolean; - response?: ResponseStub; }) { let result = await action({ request: stripDataParam(stripIndexParam(request)), context: loadContext, params, - // Only provided when single fetch is enabled, and made available via - // `defineAction` types, not `ActionFunctionArgs` - ...(singleFetch ? { response } : null), }); if (result === undefined) { @@ -76,7 +70,6 @@ export async function callRouteLoader({ request, routeId, singleFetch, - response, }: { request: Request; loader: LoaderFunction; @@ -84,15 +77,11 @@ export async function callRouteLoader({ loadContext: AppLoadContext; routeId: string; singleFetch: boolean; - response?: ResponseStub; }) { let result = await loader({ request: stripDataParam(stripIndexParam(request)), context: loadContext, params, - // Only provided when single fetch is enabled, and made available via - // `defineLoader` types, not `LoaderFunctionArgs` - ...(singleFetch ? { response } : null), }); if (result === undefined) { diff --git a/packages/remix-server-runtime/index.ts b/packages/remix-server-runtime/index.ts index c1fbfd564b2..b4ec1d6678b 100644 --- a/packages/remix-server-runtime/index.ts +++ b/packages/remix-server-runtime/index.ts @@ -8,6 +8,7 @@ export { defer, json, redirect, redirectDocument, replace } from "./responses"; export { SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, + data as unstable_data, defineLoader as unstable_defineLoader, defineAction as unstable_defineAction, } from "./single-fetch"; diff --git a/packages/remix-server-runtime/package.json b/packages/remix-server-runtime/package.json index 148fd0f0460..d2db64f905a 100644 --- a/packages/remix-server-runtime/package.json +++ b/packages/remix-server-runtime/package.json @@ -19,7 +19,7 @@ "tsc": "tsc" }, "dependencies": { - "@remix-run/router": "0.0.0-experimental-cffa549a1", + "@remix-run/router": "0.0.0-experimental-9ffbba722", "@types/cookie": "^0.6.0", "@web3-storage/multipart-parser": "^1.0.0", "cookie": "^0.6.0", diff --git a/packages/remix-server-runtime/routeModules.ts b/packages/remix-server-runtime/routeModules.ts index 8bfb68173f4..58e0ce2f7d0 100644 --- a/packages/remix-server-runtime/routeModules.ts +++ b/packages/remix-server-runtime/routeModules.ts @@ -11,7 +11,6 @@ import type { import type { AppData, AppLoadContext } from "./data"; import type { LinkDescriptor } from "./links"; import type { SerializeFrom } from "./serialize"; -import type { ResponseStub } from "./single-fetch"; export interface RouteModules { [routeId: string]: RouteModule | undefined; @@ -41,8 +40,6 @@ export type ActionFunction = ( export type ActionFunctionArgs = RRActionFunctionArgs & { // Context is always provided in Remix, and typed for module augmentation support. context: AppLoadContext; - // TODO: (v7) Make this non-optional once single-fetch is the default - response?: ResponseStub; }; /** @@ -74,8 +71,6 @@ export type LoaderFunction = ( export type LoaderFunctionArgs = RRLoaderFunctionArgs & { // Context is always provided in Remix, and typed for module augmentation support. context: AppLoadContext; - // TODO: (v7) Make this non-optional once single-fetch is the default - response?: ResponseStub; }; /** diff --git a/packages/remix-server-runtime/routes.ts b/packages/remix-server-runtime/routes.ts index 89736b4533a..029b98469d0 100644 --- a/packages/remix-server-runtime/routes.ts +++ b/packages/remix-server-runtime/routes.ts @@ -7,7 +7,6 @@ import type { import { callRouteAction, callRouteLoader } from "./data"; import type { FutureConfig } from "./entry"; import type { ServerRouteModule } from "./routeModules"; -import type { DataStrategyCtx } from "./single-fetch"; export interface RouteManifest { [routeId: string]: Route; @@ -101,8 +100,6 @@ export function createStaticHandlerDataRoutes( loader: route.module.loader!, routeId: route.id, singleFetch: future.unstable_singleFetch === true, - response: (dataStrategyCtx as DataStrategyCtx | undefined) - ?.response, }) : undefined, action: route.module.action @@ -114,8 +111,6 @@ export function createStaticHandlerDataRoutes( action: route.module.action!, routeId: route.id, singleFetch: future.unstable_singleFetch === true, - response: (dataStrategyCtx as DataStrategyCtx | undefined) - ?.response, }) : undefined, handle: route.module.handle, diff --git a/packages/remix-server-runtime/server.ts b/packages/remix-server-runtime/server.ts index 8fa3f85fa05..865bae76063 100644 --- a/packages/remix-server-runtime/server.ts +++ b/packages/remix-server-runtime/server.ts @@ -28,7 +28,6 @@ import { createStaticHandlerDataRoutes, createRoutes } from "./routes"; import { createDeferredReadableStream, isRedirectResponse, - isRedirectStatusCode, isResponse, json, } from "./responses"; @@ -36,18 +35,11 @@ import { createServerHandoffString } from "./serverHandoff"; import { getDevServerHooks } from "./dev"; import type { SingleFetchResult, SingleFetchResults } from "./single-fetch"; import { - convertResponseStubToErrorResponse, encodeViaTurboStream, - getResponseStubs, - getSingleFetchDataStrategy, getSingleFetchRedirect, - getSingleFetchResourceRouteDataStrategy, - isResponseStub, - mergeResponseStubs, singleFetchAction, singleFetchLoaders, SingleFetchRedirectSymbol, - ResponseStubOperationsSymbol, SINGLE_FETCH_REDIRECT_STATUS, } from "./single-fetch"; import { resourceRouteJsonWarning } from "./deprecations"; @@ -399,6 +391,7 @@ async function handleSingleFetchRequest( let { result, headers, status } = request.method !== "GET" ? await singleFetchAction( + build, serverMode, staticHandler, request, @@ -407,6 +400,7 @@ async function handleSingleFetchRequest( handleError ) : await singleFetchLoaders( + build, serverMode, staticHandler, request, @@ -447,13 +441,9 @@ async function handleDocumentRequest( criticalCss?: string ) { let context; - let responseStubs = getResponseStubs(); try { context = await staticHandler.query(request, { requestContext: loadContext, - unstable_dataStrategy: build.future.unstable_singleFetch - ? getSingleFetchDataStrategy(responseStubs) - : undefined, }); } catch (error: unknown) { handleError(error); @@ -464,37 +454,13 @@ async function handleDocumentRequest( return context; } - let statusCode: number; - let headers: Headers; - if (build.future.unstable_singleFetch) { - let merged = mergeResponseStubs(context, responseStubs); - statusCode = merged.statusCode; - headers = merged.headers; - - if (isRedirectStatusCode(statusCode) && headers.has("Location")) { - return new Response(null, { - status: statusCode, - headers, - }); - } - - if (context.errors) { - for (let [routeId, error] of Object.entries(context.errors)) { - if (isResponseStub(error)) { - context.errors[routeId] = convertResponseStubToErrorResponse(error); - } - } - } - } else { - statusCode = context.statusCode; - headers = getDocumentHeaders(build, context); - } + let headers = getDocumentHeaders(build, context); // Sanitize errors outside of development environments if (context.errors) { Object.values(context.errors).forEach((err) => { // @ts-expect-error `err.error` is "private" from users but intended for internal use - if ((!isRouteErrorResponse(err) || err.error) && !isResponseStub(err)) { + if (!isRouteErrorResponse(err) || err.error) { handleError(err); } }); @@ -542,7 +508,7 @@ async function handleDocumentRequest( try { return await handleDocumentRequestFunction( request, - statusCode, + context.statusCode, headers, entryContext, loadContext @@ -636,22 +602,12 @@ async function handleResourceRequest( handleError: (err: unknown) => void ) { try { - let responseStubs = build.future.unstable_singleFetch - ? getResponseStubs() - : {}; // Note we keep the routeId here to align with the Remix handling of // resource routes which doesn't take ?index into account and just takes // the leaf match let response = await staticHandler.queryRoute(request, { routeId, requestContext: loadContext, - ...(build.future.unstable_singleFetch - ? { - unstable_dataStrategy: getSingleFetchResourceRouteDataStrategy({ - responseStubs, - }), - } - : null), }); if (typeof response === "object" && response !== null) { @@ -662,36 +618,14 @@ async function handleResourceRequest( ); } - if (build.future.unstable_singleFetch) { - let stub = responseStubs[routeId]; - if (isResponse(response)) { - // If a response was returned, we use it's status and we merge our - // response stub headers onto it - let ops = stub[ResponseStubOperationsSymbol]; - for (let [op, ...args] of ops) { - // @ts-expect-error - response.headers[op](...args); - } - } else if (isResponseStub(response) || response == null) { - // If the stub or null was returned, then there is no body so we just - // proxy along the status/headers to a Response - response = new Response(null, { - status: stub.status, - headers: stub.headers, - }); - } else { - console.warn( - resourceRouteJsonWarning( - request.method === "GET" ? "loader" : "action", - routeId - ) - ); - // Otherwise we create a json Response using the stub - response = json(response, { - status: stub.status, - headers: stub.headers, - }); - } + if (build.future.unstable_singleFetch && !isResponse(response)) { + console.warn( + resourceRouteJsonWarning( + request.method === "GET" ? "loader" : "action", + routeId + ) + ); + response = json(response); } // callRouteLoader/callRouteAction always return responses (w/o single fetch). @@ -709,13 +643,6 @@ async function handleResourceRequest( return response; } - if (isResponseStub(error)) { - return new Response(null, { - status: error.status, - headers: error.headers, - }); - } - if (isRouteErrorResponse(error)) { if (error) { handleError(error); diff --git a/packages/remix-server-runtime/single-fetch.ts b/packages/remix-server-runtime/single-fetch.ts index 9fba362d23d..f6b8957a011 100644 --- a/packages/remix-server-runtime/single-fetch.ts +++ b/packages/remix-server-runtime/single-fetch.ts @@ -1,26 +1,26 @@ import type { - ActionFunctionArgs as RRActionArgs, - LoaderFunctionArgs as RRLoaderArgs, StaticHandler, unstable_DataStrategyFunctionArgs as DataStrategyFunctionArgs, unstable_DataStrategyFunction as DataStrategyFunction, - StaticHandlerContext, } from "@remix-run/router"; import { isRouteErrorResponse, + unstable_data as routerData, UNSAFE_ErrorResponseImpl as ErrorResponseImpl, } from "@remix-run/router"; import { encode } from "turbo-stream"; +import type { ServerBuild } from "./build"; import type { AppLoadContext } from "./data"; import { sanitizeError, sanitizeErrors } from "./errors"; +import { getDocumentHeaders } from "./headers"; import { ServerMode } from "./mode"; import type { TypedDeferredData, TypedResponse } from "./responses"; -import { isDeferredData, isRedirectStatusCode, isResponse } from "./responses"; +import { isRedirectStatusCode, isResponse } from "./responses"; +import type { ActionFunctionArgs, LoaderFunctionArgs } from "./routeModules"; import type { SerializeFrom } from "./serialize"; export const SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect"); -const ResponseStubActionSymbol = Symbol("ResponseStubAction"); type SingleFetchRedirectResult = { redirect: string; @@ -39,10 +39,6 @@ export type SingleFetchResults = { [SingleFetchRedirectSymbol]?: SingleFetchRedirectResult; }; -export type DataStrategyCtx = { - response: ResponseStub; -}; - // We can't use a 3xx status or else the `fetch()` would follow the redirect. // We need to communicate the redirect back as data so we can act on it in the // client side router. We use a 202 to avoid any automatic caching we might @@ -50,13 +46,13 @@ export type DataStrategyCtx = { // the user control cache behavior via Cache-Control export const SINGLE_FETCH_REDIRECT_STATUS = 202; -export function getSingleFetchDataStrategy( - responseStubs: ReturnType, - { - isActionDataRequest, - loadRouteIds, - }: { isActionDataRequest?: boolean; loadRouteIds?: string[] } = {} -): DataStrategyFunction { +export function getSingleFetchDataStrategy({ + isActionDataRequest, + loadRouteIds, +}: { + isActionDataRequest?: boolean; + loadRouteIds?: string[]; +} = {}): DataStrategyFunction { return async ({ request, matches }: DataStrategyFunctionArgs) => { // Don't call loaders on action data requests if (isActionDataRequest && request.method === "GET") { @@ -69,63 +65,12 @@ export function getSingleFetchDataStrategy( let results = await Promise.all( matches.map(async (match) => { - let responseStub: ResponseStubImpl | undefined; - if (request.method !== "GET") { - responseStub = responseStubs[ResponseStubActionSymbol]; - } else { - responseStub = responseStubs[match.route.id]; - } - let result = await match.resolve(async (handler) => { - // Cast `ResponseStubImpl -> ResponseStub` to hide the symbol in userland - let ctx: DataStrategyCtx = { response: responseStub as ResponseStub }; // Only run opt-in loaders when fine-grained revalidation is enabled let data = loadRouteIds && !loadRouteIds.includes(match.route.id) ? null - : await handler(ctx); - return { type: "data", result: data }; - }); - - // Transfer raw Response status/headers to responseStubs - if (isResponse(result.result)) { - proxyResponseToResponseStub( - result.result.status, - result.result.headers, - responseStub - ); - } else if (isDeferredData(result.result) && result.result.init) { - proxyResponseToResponseStub( - result.result.init.status, - new Headers(result.result.init.headers), - responseStub - ); - } - - return result; - }) - ); - return results; - }; -} - -export function getSingleFetchResourceRouteDataStrategy({ - responseStubs, -}: { - responseStubs: ReturnType; -}): DataStrategyFunction { - return async ({ matches }: DataStrategyFunctionArgs) => { - let results = await Promise.all( - matches.map(async (match) => { - let responseStub = match.shouldLoad - ? responseStubs[match.route.id] - : null; - let result = await match.resolve(async (handler) => { - // Cast `ResponseStubImpl -> ResponseStub` to hide the symbol in userland - let ctx: DataStrategyCtx = { - response: responseStub as ResponseStub, - }; - let data = await handler(ctx); + : await handler(); return { type: "data", result: data }; }); return result; @@ -136,6 +81,7 @@ export function getSingleFetchResourceRouteDataStrategy({ } export async function singleFetchAction( + build: ServerBuild, serverMode: ServerMode, staticHandler: StaticHandler, request: Request, @@ -152,11 +98,10 @@ export async function singleFetchAction( ...(request.body ? { duplex: "half" } : undefined), }); - let responseStubs = getResponseStubs(); let result = await staticHandler.query(handlerRequest, { requestContext: loadContext, skipLoaderErrorBubbling: true, - unstable_dataStrategy: getSingleFetchDataStrategy(responseStubs, { + unstable_dataStrategy: getSingleFetchDataStrategy({ isActionDataRequest: true, }), }); @@ -172,15 +117,11 @@ export async function singleFetchAction( } let context = result; + let headers = getDocumentHeaders(build, context); - let singleFetchResult: SingleFetchResult; - let { statusCode, headers } = mergeResponseStubs(context, responseStubs, { - isActionDataRequest: true, - }); - - if (isRedirectStatusCode(statusCode) && headers.has("Location")) { + if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) { return { - result: getSingleFetchRedirect(statusCode, headers), + result: getSingleFetchRedirect(context.statusCode, headers), headers, status: SINGLE_FETCH_REDIRECT_STATUS, }; @@ -190,20 +131,16 @@ export async function singleFetchAction( if (context.errors) { Object.values(context.errors).forEach((err) => { // @ts-expect-error This is "private" from users but intended for internal use - if ((!isRouteErrorResponse(err) || err.error) && !isResponseStub(err)) { + if (!isRouteErrorResponse(err) || err.error) { handleError(err); } }); context.errors = sanitizeErrors(context.errors, serverMode); } + let singleFetchResult: SingleFetchResult; if (context.errors) { - let error = Object.values(context.errors)[0]; - singleFetchResult = { - error: isResponseStub(error) - ? convertResponseStubToErrorResponse(error) - : error, - }; + singleFetchResult = { error: Object.values(context.errors)[0] }; } else { singleFetchResult = { data: Object.values(context.actionData || {})[0] }; } @@ -211,7 +148,7 @@ export async function singleFetchAction( return { result: singleFetchResult, headers, - status: statusCode, + status: context.statusCode, }; } catch (error) { handleError(error); @@ -225,6 +162,7 @@ export async function singleFetchAction( } export async function singleFetchLoaders( + build: ServerBuild, serverMode: ServerMode, staticHandler: StaticHandler, request: Request, @@ -240,11 +178,10 @@ export async function singleFetchLoaders( let loadRouteIds = new URL(request.url).searchParams.get("_routes")?.split(",") || undefined; - let responseStubs = getResponseStubs(); let result = await staticHandler.query(handlerRequest, { requestContext: loadContext, skipLoaderErrorBubbling: true, - unstable_dataStrategy: getSingleFetchDataStrategy(responseStubs, { + unstable_dataStrategy: getSingleFetchDataStrategy({ loadRouteIds, }), }); @@ -263,14 +200,13 @@ export async function singleFetchLoaders( } let context = result; + let headers = getDocumentHeaders(build, context); - let { statusCode, headers } = mergeResponseStubs(context, responseStubs); - - if (isRedirectStatusCode(statusCode) && headers.has("Location")) { + if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) { return { result: { [SingleFetchRedirectSymbol]: getSingleFetchRedirect( - statusCode, + context.statusCode, headers ), }, @@ -283,7 +219,7 @@ export async function singleFetchLoaders( if (context.errors) { Object.values(context.errors).forEach((err) => { // @ts-expect-error This is "private" from users but intended for internal use - if ((!isRouteErrorResponse(err) || err.error) && !isResponseStub(err)) { + if (!isRouteErrorResponse(err) || err.error) { handleError(err); } }); @@ -303,13 +239,7 @@ export async function singleFetchLoaders( let data = context.loaderData?.[m.route.id]; let error = context.errors?.[m.route.id]; if (error !== undefined) { - if (isResponseStub(error)) { - results[m.route.id] = { - error: convertResponseStubToErrorResponse(error), - }; - } else { - results[m.route.id] = { error }; - } + results[m.route.id] = { error }; } else if (data !== undefined) { results[m.route.id] = { data }; } @@ -318,7 +248,7 @@ export async function singleFetchLoaders( return { result: results, headers, - status: statusCode, + status: context.statusCode, }; } catch (error: unknown) { handleError(error); @@ -331,123 +261,6 @@ export async function singleFetchLoaders( } } -export function isResponseStub(value: any): value is ResponseStubImpl { - return ( - value && typeof value === "object" && ResponseStubOperationsSymbol in value - ); -} - -function getResponseStub(status?: number) { - let headers = new Headers(); - let operations: ResponseStubOperation[] = []; - let headersProxy = new Proxy(headers, { - get(target, prop, receiver) { - if (prop === "set" || prop === "append" || prop === "delete") { - return (name: string, value: string) => { - operations.push([prop, name, value]); - Reflect.apply(target[prop], target, [name, value]); - }; - } - return Reflect.get(target, prop, receiver); - }, - }); - return { - status, - headers: headersProxy, - [ResponseStubOperationsSymbol]: operations, - }; -} - -export function getResponseStubs() { - return new Proxy({} as Record, { - get(responseStubCache, prop) { - let cached = responseStubCache[prop]; - if (!cached) { - responseStubCache[prop] = cached = getResponseStub(); - } - return cached; - }, - }); -} - -function proxyResponseToResponseStub( - status: number | undefined, - headers: Headers, - responseStub: ResponseStubImpl -) { - if (status != null && responseStub.status == null) { - responseStub.status = status; - } - for (let [k, v] of headers) { - if (k.toLowerCase() !== "set-cookie") { - responseStub.headers.set(k, v); - } - } - - // Unsure why this is complaining? It's fine in VSCode but fails with tsc... - // @ts-ignore - ignoring instead of expecting because otherwise build fails locally - for (let v of headers.getSetCookie()) { - responseStub.headers.append("Set-Cookie", v); - } -} - -export function convertResponseStubToErrorResponse(stub: ResponseStub) { - return new ErrorResponseImpl(stub.status || 500, "", null); -} - -export function mergeResponseStubs( - context: StaticHandlerContext, - responseStubs: ReturnType, - { isActionDataRequest }: { isActionDataRequest?: boolean } = {} -) { - let statusCode: number | undefined = undefined; - let headers = new Headers(); - - // Action followed by top-down loaders - let actionStub = responseStubs[ResponseStubActionSymbol]; - let stubs = [actionStub]; - - // Nothing to merge at the route level on action data requests - if (!isActionDataRequest) { - stubs.push(...context.matches.map((m) => responseStubs[m.route.id])); - } - - for (let stub of stubs) { - // Take the highest error/redirect, or the lowest success value - preferring - // action 200's over loader 200s - if ( - // first status found on the way down - (statusCode === undefined && stub.status) || - // deeper 2xx status found while not overriding the action status - (statusCode !== undefined && - statusCode < 300 && - stub.status && - statusCode !== actionStub?.status) - ) { - statusCode = stub.status; - } - - // Replay headers operations in order - let ops = stub[ResponseStubOperationsSymbol]; - for (let [op, ...args] of ops) { - // @ts-expect-error - headers[op](...args); - } - } - - // If no response stubs set it, use whatever we got back from the router - // context which handles internal ErrorResponse cases like 404/405's where - // we may never run a loader/action - if (statusCode === undefined) { - statusCode = context.statusCode; - } - if (statusCode === undefined) { - statusCode = 200; - } - - return { statusCode, headers }; -} - export function getSingleFetchRedirect( status: number, headers: Headers @@ -522,6 +335,10 @@ export function encodeViaTurboStream( }); } +export function data(value: Serializable, init?: number | ResponseInit) { + return routerData(value, init); +} + type MaybePromise = T | Promise; type Serializable = @@ -557,44 +374,12 @@ export type Serialize = Awaited> extends TypedResponse> ? SerializeFrom : Awaited>; -export const ResponseStubOperationsSymbol = Symbol("ResponseStubOperations"); -export type ResponseStubOperation = [ - "set" | "append" | "delete", - string, - string? -]; - -/** - * A stubbed response to let you set the status/headers of your response from - * loader/action functions - */ -export type ResponseStub = { - status: number | undefined; - headers: Headers; -}; - -export type ResponseStubImpl = ResponseStub & { - [ResponseStubOperationsSymbol]: ResponseStubOperation[]; -}; - -// loader -type LoaderArgs = RRLoaderArgs & { - // Context is always provided in Remix, and typed for module augmentation support. - context: AppLoadContext; - response: ResponseStub; -}; export type Loader = ( - args: LoaderArgs + args: LoaderFunctionArgs ) => MaybePromise; export let defineLoader = (loader: T): T => loader; -// action -type ActionArgs = RRActionArgs & { - // Context is always provided in Remix, and typed for module augmentation support. - context: AppLoadContext; - response: ResponseStub; -}; export type Action = ( - args: ActionArgs + args: ActionFunctionArgs ) => MaybePromise; export let defineAction = (action: T): T => action; diff --git a/packages/remix-testing/package.json b/packages/remix-testing/package.json index cfab24a48fd..8b98e838730 100644 --- a/packages/remix-testing/package.json +++ b/packages/remix-testing/package.json @@ -21,8 +21,8 @@ "dependencies": { "@remix-run/node": "workspace:*", "@remix-run/react": "workspace:*", - "@remix-run/router": "0.0.0-experimental-cffa549a1", - "react-router-dom": "0.0.0-experimental-cffa549a1" + "@remix-run/router": "0.0.0-experimental-9ffbba722", + "react-router-dom": "0.0.0-experimental-9ffbba722" }, "devDependencies": { "@remix-run/server-runtime": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78decb38b4c..13d6ae3583f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -323,8 +323,8 @@ importers: specifier: workspace:* version: link:../packages/remix-node '@remix-run/router': - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1 + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722 '@remix-run/server-runtime': specifier: workspace:* version: link:../packages/remix-server-runtime @@ -871,8 +871,8 @@ importers: specifier: ^2.10.3 version: link:../remix-react '@remix-run/router': - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1 + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime @@ -1217,17 +1217,17 @@ importers: packages/remix-react: dependencies: '@remix-run/router': - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1 + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722 '@remix-run/server-runtime': specifier: workspace:* version: link:../remix-server-runtime react-router: - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1(react@18.2.0) + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722(react@18.2.0) react-router-dom: - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1(react-dom@18.2.0)(react@18.2.0) + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722(react-dom@18.2.0)(react@18.2.0) turbo-stream: specifier: 2.2.0 version: 2.2.0 @@ -1303,8 +1303,8 @@ importers: packages/remix-server-runtime: dependencies: '@remix-run/router': - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1 + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722 '@types/cookie': specifier: ^0.6.0 version: 0.6.0 @@ -1340,11 +1340,11 @@ importers: specifier: workspace:* version: link:../remix-react '@remix-run/router': - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1 + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722 react-router-dom: - specifier: 0.0.0-experimental-cffa549a1 - version: 0.0.0-experimental-cffa549a1(react-dom@18.2.0)(react@18.2.0) + specifier: 0.0.0-experimental-9ffbba722 + version: 0.0.0-experimental-9ffbba722(react-dom@18.2.0)(react@18.2.0) devDependencies: '@remix-run/server-runtime': specifier: workspace:* @@ -4201,8 +4201,8 @@ packages: - encoding dev: false - /@remix-run/router@0.0.0-experimental-cffa549a1: - resolution: {integrity: sha512-Pn7hkGb4NL91+wMKidAvVUxLjjWeidhBe66rfQG04BDQHoCsBvncM54KtymGprCdjM1ki06c9kcNeR3fz9rDsA==} + /@remix-run/router@0.0.0-experimental-9ffbba722: + resolution: {integrity: sha512-35QdzkxjnzP376sr25yrFpNEL3+7ClpRC7DlWYjLr3sBNhce+h1+/9tiop8ILUfcqCbnaPnb1obdqwEas0YmZA==} engines: {node: '>=14.0.0'} dev: false @@ -12786,26 +12786,26 @@ packages: engines: {node: '>=0.10.0'} dev: false - /react-router-dom@0.0.0-experimental-cffa549a1(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qnObsw+nV5pgoObJ6e+PHG8pltAvpeuqtHQX/Z8VtjQTPcXhLhXysvaE2JlQGxUNnE7OnJCLLbtk2722UvK1bQ==} + /react-router-dom@0.0.0-experimental-9ffbba722(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-ZO9bA0lefVK6jnqHSAolHCXTBYURD8/4GQDT2FHYTQoxu+cpEz2g1l/f3BM0zYG5zAFyIgVDXHXU+QB2zG+NzQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 0.0.0-experimental-cffa549a1 + '@remix-run/router': 0.0.0-experimental-9ffbba722 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 0.0.0-experimental-cffa549a1(react@18.2.0) + react-router: 0.0.0-experimental-9ffbba722(react@18.2.0) dev: false - /react-router@0.0.0-experimental-cffa549a1(react@18.2.0): - resolution: {integrity: sha512-KAdzysntJa81nnnXkm06YowOjt62hNbLph+IH7CLltLFKKdq420fdSUxZ79olJpgWEKG9fjeqLr4X/pJCEyUrg==} + /react-router@0.0.0-experimental-9ffbba722(react@18.2.0): + resolution: {integrity: sha512-Ycu8bo0VQUiMhnbYLCMSkJTUkMivT/Cbt2ff4RUIWfJCXXRCrmTIek8KOzt0ZeYkaoYiP8aQD/Gpxm4m/QgAEA==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 0.0.0-experimental-cffa549a1 + '@remix-run/router': 0.0.0-experimental-9ffbba722 react: 18.2.0 dev: false From aef2a00627e990722a45a6e2536e18ce7b667fe6 Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Thu, 25 Jul 2024 21:30:29 +0000 Subject: [PATCH 28/30] chore: format --- .changeset/remove-response-stub.md | 33 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/.changeset/remove-response-stub.md b/.changeset/remove-response-stub.md index 09b70ccded3..ae1d0347c77 100644 --- a/.changeset/remove-response-stub.md +++ b/.changeset/remove-response-stub.md @@ -5,20 +5,21 @@ Single Fetch: Remove `responseStub` in favor of `headers` -* Background - * The original Single Fetch approach was based on an assumption that an eventual `middleware` implementation would require something like `ResponseStub` so users could mutate `status`/`headers` in `middleware` before/after handlers as well as during handlers - * We wanted to align how `headers` got merged between document and data requests - * So we made document requests also use `ResponseStub` and removed the usage of `headers` in Single Fetch - * The realization/alignment between Michael and Ryan on the recent [roadmap planning](https://www.youtube.com/watch?v=f5z_axCofW0) made us realize that the original assumption was incorrect - * `middleware` won't need a stub - users can just mutate the `Response` they get from `await next()` directly - * With that gone, and still wanting to align how `headers` get merged, it makes more sense to stick with the current `headers` API and apply that to Single Fetch and avoid introducing a totally new thing in `RepsonseStub` (that always felt a bit awkward to work with anyway) +- Background -* With this change: - * You are encouraged to stop returning `Response` instances in favor of returning raw data from loaders and actions: - * ~~`return json({ data: whatever });`~~ - * `return { data: whatever };` - * In most cases, you can remove your `json()` and `defer()` calls in favor of returning raw data if they weren't setting custom `status`/`headers` - * We will be removing both `json` and `defer` in the next major version, but both _should_ still work in Single Fetch in v2 to allow for incremental adoption of the new behavior - * If you need custom `status`/`headers`: - * We've added a new `unstable_data({...}, responseInit)` utility that will let you send back `status`/`headers` alongside your raw data without having to encode it into a `Response` - * The `headers()` function will let you control header merging for both document and data requests + - The original Single Fetch approach was based on an assumption that an eventual `middleware` implementation would require something like `ResponseStub` so users could mutate `status`/`headers` in `middleware` before/after handlers as well as during handlers + - We wanted to align how `headers` got merged between document and data requests + - So we made document requests also use `ResponseStub` and removed the usage of `headers` in Single Fetch + - The realization/alignment between Michael and Ryan on the recent [roadmap planning](https://www.youtube.com/watch?v=f5z_axCofW0) made us realize that the original assumption was incorrect + - `middleware` won't need a stub - users can just mutate the `Response` they get from `await next()` directly + - With that gone, and still wanting to align how `headers` get merged, it makes more sense to stick with the current `headers` API and apply that to Single Fetch and avoid introducing a totally new thing in `RepsonseStub` (that always felt a bit awkward to work with anyway) + +- With this change: + - You are encouraged to stop returning `Response` instances in favor of returning raw data from loaders and actions: + - ~~`return json({ data: whatever });`~~ + - `return { data: whatever };` + - In most cases, you can remove your `json()` and `defer()` calls in favor of returning raw data if they weren't setting custom `status`/`headers` + - We will be removing both `json` and `defer` in the next major version, but both _should_ still work in Single Fetch in v2 to allow for incremental adoption of the new behavior + - If you need custom `status`/`headers`: + - We've added a new `unstable_data({...}, responseInit)` utility that will let you send back `status`/`headers` alongside your raw data without having to encode it into a `Response` + - The `headers()` function will let you control header merging for both document and data requests From 08731d944a3785f5541bc38ef4493c8939103e53 Mon Sep 17 00:00:00 2001 From: Brett Scott Date: Fri, 26 Jul 2024 03:06:11 +0100 Subject: [PATCH 29/30] Include .client/.server directories in Tailwind globs (#9758) Co-authored-by: Mark Dalgleish --- contributors.yml | 1 + docs/styling/tailwind.md | 2 +- integration/hmr-test.ts | 2 +- integration/postcss-test.ts | 2 +- integration/tailwind-test.ts | 6 +++--- scripts/playground/template/tailwind.config.js | 2 +- templates/cloudflare-workers/tailwind.config.ts | 2 +- templates/cloudflare/tailwind.config.ts | 2 +- templates/express/tailwind.config.ts | 2 +- templates/remix-javascript/tailwind.config.js | 2 +- templates/remix/tailwind.config.ts | 2 +- templates/spa/tailwind.config.ts | 2 +- 12 files changed, 14 insertions(+), 13 deletions(-) diff --git a/contributors.yml b/contributors.yml index b6819cc3254..7c49107b888 100644 --- a/contributors.yml +++ b/contributors.yml @@ -83,6 +83,7 @@ - bogas04 - BogdanDevBst - bolchowka +- brettscott - brookslybrand - brophdawg11 - bruno-oliveira diff --git a/docs/styling/tailwind.md b/docs/styling/tailwind.md index 67766cb3f56..e0e0c25bb65 100644 --- a/docs/styling/tailwind.md +++ b/docs/styling/tailwind.md @@ -32,7 +32,7 @@ Now we can tell it which files to generate classes from: import type { Config } from "tailwindcss"; export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/integration/hmr-test.ts b/integration/hmr-test.ts index a2f5f2ad2a3..b42e40c962b 100644 --- a/integration/hmr-test.ts +++ b/integration/hmr-test.ts @@ -25,7 +25,7 @@ let files = { "tailwind.config.js": js` /** @type {import('tailwindcss').Config} */ export default { - content: ["./app/**/*.{ts,tsx,jsx,js}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/integration/postcss-test.ts b/integration/postcss-test.ts index fa13186e861..fcc8e5f55c1 100644 --- a/integration/postcss-test.ts +++ b/integration/postcss-test.ts @@ -89,7 +89,7 @@ test.describe("PostCSS enabled", () => { `, "tailwind.config.js": js` export default { - content: ["./app/**/*.{ts,tsx,jsx,js}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { spacing: { 'test': ${JSON.stringify(TEST_PADDING_VALUE)} diff --git a/integration/tailwind-test.ts b/integration/tailwind-test.ts index 4f2f91ce155..3a184aa046b 100644 --- a/integration/tailwind-test.ts +++ b/integration/tailwind-test.ts @@ -23,7 +23,7 @@ function runTests(ext: typeof extensions[number]) { let tailwindConfig = ["mjs", "ts", "js"].includes(ext) ? js` export default { - content: ["./app/**/*.{ts,tsx,jsx,js}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { spacing: { 'test': ${JSON.stringify(TEST_PADDING_VALUE)} @@ -33,7 +33,7 @@ function runTests(ext: typeof extensions[number]) { ` : js` module.exports = { - content: ["./app/**/*.{ts,tsx,jsx,js}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { spacing: { 'test': ${JSON.stringify(TEST_PADDING_VALUE)} @@ -364,7 +364,7 @@ test.describe("Tailwind disabled", () => { files: { "tailwind.config.js": js` module.exports = { - content: ["./app/**/*.{ts,tsx,jsx,js}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { spacing: { 'test': ${JSON.stringify(TEST_PADDING_VALUE)} diff --git a/scripts/playground/template/tailwind.config.js b/scripts/playground/template/tailwind.config.js index 8cff356f461..44a7b02ac1f 100644 --- a/scripts/playground/template/tailwind.config.js +++ b/scripts/playground/template/tailwind.config.js @@ -1,6 +1,6 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./app/**/*.{ts,tsx,jsx,js}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/templates/cloudflare-workers/tailwind.config.ts b/templates/cloudflare-workers/tailwind.config.ts index 64a5243e4d0..34d03da55f6 100644 --- a/templates/cloudflare-workers/tailwind.config.ts +++ b/templates/cloudflare-workers/tailwind.config.ts @@ -1,7 +1,7 @@ import type { Config } from "tailwindcss"; export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/templates/cloudflare/tailwind.config.ts b/templates/cloudflare/tailwind.config.ts index 64a5243e4d0..34d03da55f6 100644 --- a/templates/cloudflare/tailwind.config.ts +++ b/templates/cloudflare/tailwind.config.ts @@ -1,7 +1,7 @@ import type { Config } from "tailwindcss"; export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/templates/express/tailwind.config.ts b/templates/express/tailwind.config.ts index 64a5243e4d0..34d03da55f6 100644 --- a/templates/express/tailwind.config.ts +++ b/templates/express/tailwind.config.ts @@ -1,7 +1,7 @@ import type { Config } from "tailwindcss"; export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/templates/remix-javascript/tailwind.config.js b/templates/remix-javascript/tailwind.config.js index e015c8a89f9..49d20d5defe 100644 --- a/templates/remix-javascript/tailwind.config.js +++ b/templates/remix-javascript/tailwind.config.js @@ -1,5 +1,5 @@ export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/templates/remix/tailwind.config.ts b/templates/remix/tailwind.config.ts index 64a5243e4d0..34d03da55f6 100644 --- a/templates/remix/tailwind.config.ts +++ b/templates/remix/tailwind.config.ts @@ -1,7 +1,7 @@ import type { Config } from "tailwindcss"; export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, diff --git a/templates/spa/tailwind.config.ts b/templates/spa/tailwind.config.ts index 64a5243e4d0..34d03da55f6 100644 --- a/templates/spa/tailwind.config.ts +++ b/templates/spa/tailwind.config.ts @@ -1,7 +1,7 @@ import type { Config } from "tailwindcss"; export default { - content: ["./app/**/*.{js,jsx,ts,tsx}"], + content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], theme: { extend: {}, }, From 1ac5c50dd227a594fa9e9f5003df40708bff97ca Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Fri, 26 Jul 2024 02:07:25 +0000 Subject: [PATCH 30/30] chore: format --- docs/styling/tailwind.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/styling/tailwind.md b/docs/styling/tailwind.md index e0e0c25bb65..4ca0f68ee9b 100644 --- a/docs/styling/tailwind.md +++ b/docs/styling/tailwind.md @@ -32,7 +32,9 @@ Now we can tell it which files to generate classes from: import type { Config } from "tailwindcss"; export default { - content: ["./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}"], + content: [ + "./app/**/{**,.client,.server}/**/*.{js,jsx,ts,tsx}", + ], theme: { extend: {}, },