[Segment Cache] use `loading` from dynamic response for unprefetched navigations (#83305)
If we're navigating to a page without a prefetch, we obviously can't
show an instant loading state. However, if the page has a `loading.tsx`,
then the loading component will still stream in as part of the dynamic
response, and we should use it to render a loading boundary around the
page content. If we don't, then the navigation will block until the
content resolves into something renderable (either finishes or manages
to render a suspense boundary of its own).
This wasn't being done because `createPendingCacheNode` (used for
unprefetched navigations) was always setting `loading` to `null`, and
then was never updated with the `loading` received from the dynamic
response. With this PR, if we don't already have a prefetched loading
state, we'll now handle `loading` the same as we do `rsc` (the segment's
content) -- we'll create a deferred promise for `loading` and resolve it
when the relevant segment streams in.
Note that before the deferred promise is resolved, the relevant
`LoadingBoundary` itself will suspend on it, but since it sits right
above `rsc` (and is in a new subtree) we won't hide any more contents
than we would when suspending on the `rsc` promise -- we don't have a
prefetch, so we won't have an existing loading state to display there
anyway.
Also I had to do some typescript tweaks to `createDeferredRsc` to allow
it to contain a more specific type than `ReactNode`. it's a bit noisy,
so that's pulled out into a separate commit for ease of review.