Allow server functions to be used as client component props in `'use cache'` (#81431)
When passing server actions or nested `'use cache'` functions inside of
cached components as props to client components, we need to make sure
that those are registered as server references, even when restoring the
parent component from the cache, e.g. during the resume of a partially
static shell. Otherwise, React would throw a runtime error while trying
to serialize the props.
<details>
<summary>Example</summary>
```tsx
import { connection } from 'next/server'
import { Suspense } from 'react'
export default function Page() {
return (
<div>
<Suspense fallback={<h1>Loading...</h1>}>
<Dynamic />
</Suspense>
<CachedForm />
</div>
)
}
const Dynamic = async () => {
await connection()
return <h1>Dynamic</h1>
}
async function CachedForm() {
'use cache'
return (
<form
action={async () => {
'use server'
console.log('Hello, World!')
}}
>
<button>Submit</button>
</form>
)
}
```
</details>
Previously, for inline server functions, the Next.js compiler placed the
`registerServerReference` calls where the server function was originally
declared. When the enclosing function was restored from a cache, this
call was skipped and the reference was not registered, leading to the
serialization error. To fix it, we can hoist the
`registerServerReference` call into the module scope, where the
reference itself also has been hoisted to. For simplicity, we're doing
this now generally, regardless of whether the server function is inline
or top-level.
Note: Since `registerServerReference` uses `Object.defineProperties` to
mutate the given reference, we don't need to assign the result to
anything. We already did this for exported functions of a module with a
top-level `'use server'` directive.
closes NAR-167