diff --git a/packages/plugin-rsc/e2e/react-router.test.ts b/packages/plugin-rsc/e2e/react-router.test.ts index 4c63a75e9..f958b7966 100644 --- a/packages/plugin-rsc/e2e/react-router.test.ts +++ b/packages/plugin-rsc/e2e/react-router.test.ts @@ -120,6 +120,27 @@ function defineTest(f: Fixture) { await page.getByText('This is the home [edit] page.').click() }) + + test('server hmr for a glob-loaded component under a client boundary', async ({ + page, + }) => { + await page.goto(f.url('/')) + await waitForHydration(page) + await using _ = await expectNoReload(page) + + const component = page.getByTestId('workflow-component') + await expect(component).toHaveText('Workflow component: before') + + const editor = f.createEditor( + 'app/routes/home-components/workflow-component.tsx', + ) + await editor.edit((contents) => contents.replace('before', 'after')) + + await expect(component).toHaveText('Workflow component: after') + + await editor.reset() + await expect(component).toHaveText('Workflow component: before') + }) }) test('server css code split', async ({ page }) => { diff --git a/packages/plugin-rsc/e2e/server-module-hmr.test.ts b/packages/plugin-rsc/e2e/server-module-hmr.test.ts new file mode 100644 index 000000000..8ae9756ab --- /dev/null +++ b/packages/plugin-rsc/e2e/server-module-hmr.test.ts @@ -0,0 +1,21 @@ +import { expect, test } from '@playwright/test' +import { useFixture } from './fixture' +import { expectNoReload, waitForHydration } from './helper' + +const f = useFixture({ root: 'examples/server-module-hmr', mode: 'dev' }) + +test('refreshes a glob-loaded server module behind a client boundary', async ({ + page, +}) => { + await page.goto(f.url()) + await waitForHydration(page) + await using _ = await expectNoReload(page) + + const component = page.getByTestId('workflow-component') + await expect(component).toHaveText('Workflow component: before') + + const editor = f.createEditor('app/workflow-components/demo/component.tsx') + await editor.edit((contents) => contents.replace('before', 'after')) + + await expect(component).toHaveText('Workflow component: after') +}) diff --git a/packages/plugin-rsc/examples/react-router/app/routes/home-components/workflow-component.tsx b/packages/plugin-rsc/examples/react-router/app/routes/home-components/workflow-component.tsx new file mode 100644 index 000000000..25d08c3f4 --- /dev/null +++ b/packages/plugin-rsc/examples/react-router/app/routes/home-components/workflow-component.tsx @@ -0,0 +1,3 @@ +export default function WorkflowComponent() { + return

Workflow component: before

+} diff --git a/packages/plugin-rsc/examples/react-router/app/routes/home.tsx b/packages/plugin-rsc/examples/react-router/app/routes/home.tsx index fdaf9db31..ff0c27640 100644 --- a/packages/plugin-rsc/examples/react-router/app/routes/home.tsx +++ b/packages/plugin-rsc/examples/react-router/app/routes/home.tsx @@ -1,9 +1,22 @@ +import type { ComponentType } from 'react' import { sayHello } from './home.actions.ts' -import { PendingButton } from './home.client.tsx' import './home.css' +import { PendingButton } from './home.client.tsx' import { TestActionStateServer } from './test-action-state/server.tsx' -const Component = () => { +type WorkflowComponentModule = { + default: ComponentType +} + +const workflowComponentModules = import.meta.glob( + './home-components/*.tsx', +) +const loadWorkflowComponent = + workflowComponentModules['./home-components/workflow-component.tsx']! + +const Component = async () => { + const WorkflowComponent = (await loadWorkflowComponent()).default + return (
@@ -34,6 +47,7 @@ const Component = () => {
+
) diff --git a/packages/plugin-rsc/examples/server-module-hmr/.gitignore b/packages/plugin-rsc/examples/server-module-hmr/.gitignore new file mode 100644 index 000000000..f247e8d8e --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +build/ +.react-router/ \ No newline at end of file diff --git a/packages/plugin-rsc/examples/server-module-hmr/README.md b/packages/plugin-rsc/examples/server-module-hmr/README.md new file mode 100644 index 000000000..82346910e --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/README.md @@ -0,0 +1,5 @@ +# RSC Server Module HMR Reproduction + +This app loads a server component through `import.meta.glob` and passes its rendered output to a client component. + +Run `pnpm dev`, open the printed URL, and edit `app/workflow-components/demo/component.tsx`. Before the HMR fix, the page keeps the old text until a full reload. diff --git a/packages/plugin-rsc/examples/server-module-hmr/app/components/client-page.tsx b/packages/plugin-rsc/examples/server-module-hmr/app/components/client-page.tsx new file mode 100644 index 000000000..ce48b2d14 --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/app/components/client-page.tsx @@ -0,0 +1,7 @@ +'use client' + +import type { ReactNode } from 'react' + +export function ClientPage({ children }: { children: ReactNode }) { + return
{children}
+} diff --git a/packages/plugin-rsc/examples/server-module-hmr/app/root.tsx b/packages/plugin-rsc/examples/server-module-hmr/app/root.tsx new file mode 100644 index 000000000..93611c2ce --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/app/root.tsx @@ -0,0 +1,18 @@ +import { Links, Meta, Outlet } from 'react-router' + +export function Layout({ children }: { children: React.ReactNode }) { + return ( + + + + + + + {children} + + ) +} + +export default function Root() { + return +} diff --git a/packages/plugin-rsc/examples/server-module-hmr/app/routes.ts b/packages/plugin-rsc/examples/server-module-hmr/app/routes.ts new file mode 100644 index 000000000..0f04fff0e --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/app/routes.ts @@ -0,0 +1,3 @@ +import { index, layout } from '@react-router/dev/routes' + +export default [layout('./routes/layout.tsx', [index('./routes/index.tsx')])] diff --git a/packages/plugin-rsc/examples/server-module-hmr/app/routes/index.tsx b/packages/plugin-rsc/examples/server-module-hmr/app/routes/index.tsx new file mode 100644 index 000000000..de670d752 --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/app/routes/index.tsx @@ -0,0 +1,3 @@ +export default function Home() { + return

Home route

+} diff --git a/packages/plugin-rsc/examples/server-module-hmr/app/routes/layout.tsx b/packages/plugin-rsc/examples/server-module-hmr/app/routes/layout.tsx new file mode 100644 index 000000000..1b604f1c6 --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/app/routes/layout.tsx @@ -0,0 +1,29 @@ +import type { ReactNode } from 'react' +import { Outlet } from 'react-router' +import { ClientPage } from '../components/client-page' + +type WorkflowComponentModule = { + default: () => ReactNode +} + +const workflowModules = import.meta.glob( + '../workflow-components/*/component.tsx', +) + +export function loader() { + return { ready: true } +} + +export async function ServerComponent() { + const loadWorkflow = + workflowModules['../workflow-components/demo/component.tsx']! + const workflowModule = await loadWorkflow() + const WorkflowComponent = workflowModule.default + + return ( + + + + + ) +} diff --git a/packages/plugin-rsc/examples/server-module-hmr/app/workflow-components/demo/component.tsx b/packages/plugin-rsc/examples/server-module-hmr/app/workflow-components/demo/component.tsx new file mode 100644 index 000000000..25d08c3f4 --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/app/workflow-components/demo/component.tsx @@ -0,0 +1,3 @@ +export default function WorkflowComponent() { + return

Workflow component: before

+} diff --git a/packages/plugin-rsc/examples/server-module-hmr/package.json b/packages/plugin-rsc/examples/server-module-hmr/package.json new file mode 100644 index 000000000..31965aaaf --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/package.json @@ -0,0 +1,23 @@ +{ + "name": "@vitejs/plugin-rsc-examples-server-module-hmr", + "private": true, + "license": "MIT", + "type": "module", + "scripts": { + "dev": "react-router dev", + "build": "react-router build" + }, + "dependencies": { + "@react-router/node": "8.5.0", + "react": "^19.3.1", + "react-dom": "^19.3.1", + "react-router": "8.5.0", + "react-server-dom-webpack": "^19.3.1" + }, + "devDependencies": { + "@react-router/dev": "8.5.0", + "@vitejs/plugin-react": "workspace:*", + "@vitejs/plugin-rsc": "workspace:*", + "vite": "^8.3.4" + } +} diff --git a/packages/plugin-rsc/examples/server-module-hmr/react-router.config.ts b/packages/plugin-rsc/examples/server-module-hmr/react-router.config.ts new file mode 100644 index 000000000..348ea9ad6 --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/react-router.config.ts @@ -0,0 +1,12 @@ +export default { + appDirectory: 'app', + buildDirectory: 'build', + ssr: true, + routeDiscovery: { + mode: 'lazy', + }, + future: { + unstable_enableNodeReadableStream: true, + unstable_optimizeDeps: true, + }, +} diff --git a/packages/plugin-rsc/examples/server-module-hmr/vite.config.ts b/packages/plugin-rsc/examples/server-module-hmr/vite.config.ts new file mode 100644 index 000000000..761efbbb7 --- /dev/null +++ b/packages/plugin-rsc/examples/server-module-hmr/vite.config.ts @@ -0,0 +1,12 @@ +import { unstable_reactRouterRSC as reactRouterRSC } from '@react-router/dev/vite' +import react from '@vitejs/plugin-react' +import rsc from '@vitejs/plugin-rsc' +import { defineConfig } from 'vite' + +export default defineConfig({ + plugins: [ + reactRouterRSC({ __runningWithinTheReactRouterMonoRepo: true }), + react(), + rsc(), + ], +}) diff --git a/packages/plugin-rsc/src/plugin.ts b/packages/plugin-rsc/src/plugin.ts index 6cb24453e..92aedd73b 100644 --- a/packages/plugin-rsc/src/plugin.ts +++ b/packages/plugin-rsc/src/plugin.ts @@ -823,7 +823,13 @@ export default function vitePluginRsc( return mods.some((mod) => recurse(mod)) } - if (!isInsideClientBoundary(ctx.modules)) { + if ( + !isInsideClientBoundary(ctx.modules) || + (this.environment.name === 'rsc' && + !ctx.modules.some( + (mod) => mod.id && manager.clientReferenceMetaMap[mod.id], + )) + ) { if (this.environment.name === 'rsc') { // detect if this module is only created as css deps (e.g. tailwind) // (NOTE: this is not necessary since Vite 7.1.0-beta.0 https://github.com/vitejs/vite/pull/20391 ) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8b159afb..cbfa94ec1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -915,6 +915,37 @@ importers: specifier: ^4.151.2 version: 4.151.2(@types/node@24.19.2) + packages/plugin-rsc/examples/server-module-hmr: + dependencies: + '@react-router/node': + specifier: 8.5.0 + version: 8.5.0(react-router@8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(typescript@7.0.2) + react: + specifier: ^19.3.1 + version: 19.3.1 + react-dom: + specifier: ^19.3.1 + version: 19.3.1(react@19.3.1) + react-router: + specifier: 8.5.0 + version: 8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + react-server-dom-webpack: + specifier: ^19.3.1 + version: 19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + devDependencies: + '@react-router/dev': + specifier: 8.5.0 + version: 8.5.0(@vitejs/plugin-rsc@packages+plugin-rsc)(babel-plugin-macros@3.1.0)(react-router@8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(typescript@7.0.2)(vite@8.3.4(@types/node@24.19.2)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1))(wrangler@4.151.2(@types/node@24.19.2)) + '@vitejs/plugin-react': + specifier: workspace:* + version: link:../../../plugin-react + '@vitejs/plugin-rsc': + specifier: workspace:* + version: link:../.. + vite: + specifier: ^8.3.4 + version: 8.3.4(@types/node@24.19.2)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1) + packages/plugin-rsc/examples/source-map: dependencies: react: @@ -2566,6 +2597,43 @@ packages: '@quansync/fs@1.0.0': resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==} + '@react-router/dev@8.5.0': + resolution: {integrity: sha512-SXmL0ym9Wp8Hi0LdXLG6yPaN8V1rUW4PuavvBS9eqpr0hM3PFjiCUT44pRzCj4G9lKEQBeNcj4beOtpN7IxuCg==} + engines: {node: '>=22.22.0'} + hasBin: true + peerDependencies: + '@react-router/serve': ^8.5.0 + '@vitejs/plugin-rsc': ~0.5.26 + react-router: ^8.5.0 + react-server-dom-webpack: ^19.2.7 + typescript: ^5.1.0 || ^6.0.0 || ^7.0.0 + vite: ^7.0.0 || ^8.0.0 + wrangler: ^4.0.0 + peerDependenciesMeta: + '@react-router/serve': + optional: true + '@vitejs/plugin-rsc': + optional: true + react-server-dom-webpack: + optional: true + typescript: + optional: true + wrangler: + optional: true + + '@react-router/node@8.5.0': + resolution: {integrity: sha512-9a3a37TW5GAo/J336Uk1tca/X1OxjpseETz/zCHcojtL7oRlFrlFoDt6wSdCtFRCiwlLyHcWY+qwZ+xnb05kSg==} + engines: {node: '>=22.22.0'} + peerDependencies: + react-router: 8.5.0 + typescript: ^5.1.0 || ^6.0.0 || ^7.0.0 + peerDependenciesMeta: + typescript: + optional: true + + '@remix-run/node-fetch-server@0.14.2': + resolution: {integrity: sha512-1cpM/f5i1ka/9CUMBwZXZp7Bn92x8VQjzg+F4eEe88DlVdNHkAKrf/vvbZoYgdkfy2bWHtGC6LQGLmojEqOF4Q==} + '@remix-run/route-pattern@0.22.1': resolution: {integrity: sha512-czdGJWh09Lapvcqt7Vb09KlrU2PhRJ8xQaI+AItTuD9aDJ5MAgxnS38lnys6Ll+6RJEqPiaUqTwIQhVLwFvv+w==} @@ -3326,6 +3394,9 @@ packages: resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} hasBin: true + babel-dead-code-elimination@1.0.12: + resolution: {integrity: sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig==} + babel-plugin-macros@3.1.0: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} @@ -3396,6 +3467,10 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} @@ -3507,6 +3582,14 @@ packages: decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + default-browser-id@5.0.1: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} @@ -3666,6 +3749,10 @@ packages: estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + exit-hook@5.1.0: + resolution: {integrity: sha512-INjr2xyxHo7bhAqf5ong++GZPPnpcuBcaXUKt03yf7Fie9yWD7FapL4teOU0+awQazGs5ucBh7xWs/AD+6nhog==} + engines: {node: '>=20'} + expect-type@1.4.0: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} @@ -3844,6 +3931,10 @@ packages: resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} engines: {node: '>=16'} + isbot@5.2.2: + resolution: {integrity: sha512-iQcBXcd+Rv/pkubRyGh2utW2j1oPG5hZY6TUhVPpqK4G+o3IbxpJNx04hgksjc/N7GK5pEorUxDeg31cFgEk/w==} + engines: {node: '>=18'} + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true @@ -3867,6 +3958,11 @@ packages: engines: {node: '>=6'} hasBin: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -4050,6 +4146,9 @@ packages: resolution: {integrity: sha512-++gUqRDEvcnN6Zhqrr+y/CkVEHhlrR96vZn3nZZPYzMcBUyBtTKzB9NadClFIsIVSsu+3i9tfk/erqy9kAmt7Q==} engines: {node: '>=14'} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -4286,6 +4385,10 @@ packages: vite-plus: optional: true + p-map@7.1.1: + resolution: {integrity: sha512-6Lh3jQPLthYujSrlw6ccWXBGZTkoTCz27Hd92g79LH/kjAbgoEu0t442cCCNbegPSJsA0lwDX8z0bcKtkpA32g==} + engines: {node: '>=18'} + package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} @@ -4410,6 +4513,10 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + react-router@8.5.0: resolution: {integrity: sha512-9nEd/deifcTJIIcUaNIyQGkyXD0D6QVB9XD2O5GgHpP3xu3U5RXm87YQ8++Wn8JQWgMBM/5+PjWPM/7n7O7WHA==} engines: {node: '>=22.22.0'} @@ -4448,6 +4555,10 @@ packages: resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==} engines: {node: '>=0.10.0'} + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + refa@0.12.1: resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -4812,6 +4923,14 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + valibot@1.5.0: + resolution: {integrity: sha512-nil6AkP2TChWL43Z5uJ6GTxX01CUA+g8LWUM+N/rB9NBbkUMaUsi9PUNzlUPgoKASgmx9f7eGOYpJ04/fSa6FQ==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + verkit@0.5.0: resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} engines: {node: '>=18.12.0'} @@ -5875,6 +5994,51 @@ snapshots: dependencies: quansync: 1.0.0 + '@react-router/dev@8.5.0(@vitejs/plugin-rsc@packages+plugin-rsc)(babel-plugin-macros@3.1.0)(react-router@8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(react-server-dom-webpack@19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(typescript@7.0.2)(vite@8.3.4(@types/node@24.19.2)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1))(wrangler@4.151.2(@types/node@24.19.2))': + dependencies: + '@babel/core': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + '@react-router/node': 8.5.0(react-router@8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(typescript@7.0.2) + '@remix-run/node-fetch-server': 0.14.2 + babel-dead-code-elimination: 1.0.12 + chokidar: 5.0.0 + dedent: 1.7.2(babel-plugin-macros@3.1.0) + es-module-lexer: 2.3.2 + exit-hook: 5.1.0 + isbot: 5.2.2 + jsesc: 3.1.0 + lodash: 4.18.1 + p-map: 7.1.1 + pathe: 2.0.3 + picocolors: 1.1.1 + pkg-types: 2.3.3 + react-refresh: 0.18.0 + react-router: 8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + semver: 7.8.5 + tinyglobby: 0.2.17 + valibot: 1.5.0(typescript@7.0.2) + vite: 8.3.4(@types/node@24.19.2)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.1) + optionalDependencies: + '@vitejs/plugin-rsc': link:packages/plugin-rsc + react-server-dom-webpack: 19.3.1(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + typescript: 7.0.2 + wrangler: 4.151.2(@types/node@24.19.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + '@react-router/node@8.5.0(react-router@8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1))(typescript@7.0.2)': + dependencies: + '@remix-run/node-fetch-server': 0.14.2 + react-router: 8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1) + optionalDependencies: + typescript: 7.0.2 + + '@remix-run/node-fetch-server@0.14.2': {} + '@remix-run/route-pattern@0.22.1': {} '@rolldown/binding-android-arm-eabi@1.2.14': @@ -6420,6 +6584,15 @@ snapshots: astring@1.8.6: {} + babel-dead-code-elimination@1.0.12: + dependencies: + '@babel/core': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/traverse': 7.29.7 + '@babel/types': 7.29.7 + transitivePeerDependencies: + - supports-color + babel-plugin-macros@3.1.0: dependencies: '@babel/runtime': 7.23.5 @@ -6478,6 +6651,10 @@ snapshots: character-reference-invalid@2.0.1: {} + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + collapse-white-space@2.1.0: {} comma-separated-tokens@2.0.3: {} @@ -6576,6 +6753,10 @@ snapshots: dependencies: character-entities: 2.0.2 + dedent@1.7.2(babel-plugin-macros@3.1.0): + optionalDependencies: + babel-plugin-macros: 3.1.0 + default-browser-id@5.0.1: {} default-browser@5.5.1: @@ -6739,6 +6920,8 @@ snapshots: dependencies: '@types/estree': 1.0.9 + exit-hook@5.1.0: {} + expect-type@1.4.0: {} exsolve@1.1.3: {} @@ -6921,6 +7104,8 @@ snapshots: dependencies: is-inside-container: 1.0.0 + isbot@5.2.2: {} + jiti@2.7.0: {} js-tokens@10.0.0: {} @@ -6937,6 +7122,8 @@ snapshots: jsesc@3.0.2: {} + jsesc@3.1.0: {} + json-parse-even-better-errors@2.3.1: {} json5@2.2.3: {} @@ -7070,6 +7257,8 @@ snapshots: pkg-types: 2.3.3 quansync: 0.2.11 + lodash@4.18.1: {} + longest-streak@3.1.0: {} loose-envify@1.4.0: @@ -7548,6 +7737,8 @@ snapshots: '@oxlint/binding-win32-x64-msvc': 1.89.0 oxlint-tsgolint: 7.0.2004 + p-map@7.1.1: {} + package-manager-detector@1.8.0: {} parent-module@1.0.1: @@ -7674,6 +7865,8 @@ snapshots: react-is@16.13.1: {} + react-refresh@0.18.0: {} + react-router@8.5.0(@types/react-dom@19.3.0(@types/react@19.3.0))(@types/react@19.3.0)(react-dom@19.3.1(react@19.3.1))(react@19.3.1): dependencies: '@remix-run/route-pattern': 0.22.1 @@ -7704,6 +7897,8 @@ snapshots: react@19.3.1: {} + readdirp@5.1.1: {} + refa@0.12.1: dependencies: '@eslint-community/regexpp': 4.12.2 @@ -8080,6 +8275,10 @@ snapshots: utils-merge@1.0.1: {} + valibot@1.5.0(typescript@7.0.2): + optionalDependencies: + typescript: 7.0.2 + verkit@0.5.0: {} vfile-message@4.0.2: