diff --git a/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx b/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx index 2be819e8ff67..8bba2b6762bd 100644 --- a/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx +++ b/packages/next-swc/crates/next-core/js/src/entry/app/hydrate.tsx @@ -4,6 +4,7 @@ import type { ReactElement } from "react"; // @ts-expect-error import { version } from "next/package.json"; import { createFromReadableStream } from "next/dist/compiled/react-server-dom-webpack/client"; +import { callServer } from 'next/dist/client/app-call-server'; import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context"; @@ -109,7 +110,7 @@ function useInitialServerResponse(cacheKey: string) { }, }); - const newResponse = createFromReadableStream(readable); + const newResponse = createFromReadableStream(readable, { callServer }); rscCache.set(cacheKey, newResponse); return newResponse; diff --git a/packages/next/src/client/components/router-reducer/fetch-server-response.ts b/packages/next/src/client/components/router-reducer/fetch-server-response.ts index 8a1efbbae715..ff6e079a73a8 100644 --- a/packages/next/src/client/components/router-reducer/fetch-server-response.ts +++ b/packages/next/src/client/components/router-reducer/fetch-server-response.ts @@ -12,6 +12,7 @@ import { RSC_CONTENT_TYPE_HEADER, } from '../app-router-headers' import { urlToUrlWithoutFlightMarker } from '../app-router' +import { callServer } from '../../app-call-server' /** * Fetch the flight data for the provided url. Takes in the current router state to decide what to render server-side. @@ -75,7 +76,9 @@ export async function fetchServerResponse( } // Handle the `fetch` readable stream that can be unwrapped by `React.use`. - const flightData: FlightData = await createFromFetch(Promise.resolve(res)) + const flightData: FlightData = await createFromFetch(Promise.resolve(res), { + callServer, + }) return [flightData, canonicalUrl] } catch (err) { console.error( diff --git a/test/e2e/app-dir/actions/app-action.test.ts b/test/e2e/app-dir/actions/app-action.test.ts index d85a78e295dd..804e425aaad3 100644 --- a/test/e2e/app-dir/actions/app-action.test.ts +++ b/test/e2e/app-dir/actions/app-action.test.ts @@ -7,7 +7,7 @@ createNextDescribe( files: __dirname, skipDeployment: true, }, - ({ next }) => { + ({ next, isNextDev }) => { it('should handle basic actions correctly', async () => { const browser = await next.browser('/server') @@ -83,5 +83,34 @@ createNextDescribe( await browser.elementByCss('#dec').click() await check(() => browser.elementByCss('h1').text(), '3') }) + + if (isNextDev) { + describe('HMR', () => { + it('should support updating the action', async () => { + const filePath = 'app/server/actions.js' + const origContent = await next.readFile(filePath) + + try { + const browser = await next.browser('/server') + + const cnt = await browser.elementByCss('h1').text() + expect(cnt).toBe('0') + + await browser.elementByCss('#inc').click() + await check(() => browser.elementByCss('h1').text(), '1') + + await next.patchFile( + filePath, + origContent.replace('return value + 1', 'return value + 1000') + ) + + await browser.elementByCss('#inc').click() + await check(() => browser.elementByCss('h1').text(), '1001') + } finally { + await next.patchFile(filePath, origContent) + } + }) + }) + } } )