33import { type Node , type Element } from 'react'
44import type {
55 Visitor ,
6+ ClientReferenceVisitor ,
67 YieldFrame ,
78 Frame ,
89 AbstractElement ,
@@ -18,7 +19,9 @@ import {
1819 getCurrentErrorFrame ,
1920 setCurrentRendererState ,
2021 initRendererState ,
21- Dispatcher
22+ Dispatcher ,
23+ readContextValue ,
24+ setContextValue
2225} from './internals'
2326
2427/** visit() walks all elements (depth-first) and while it walks the
@@ -29,6 +32,7 @@ import {
2932const flushFrames = (
3033 queue : Frame [ ] ,
3134 visitor : Visitor ,
35+ clientRefVisitor : ClientReferenceVisitor ,
3236 state : RendererState
3337) : Promise < void > => {
3438 const frame = queue . shift ( )
@@ -45,21 +49,30 @@ const flushFrames = (
4549 return Promise . resolve ( frame . thenable ) . then (
4650 ( ) => {
4751 setCurrentRendererState ( state )
48- update ( frame , queue , visitor )
49- return flushFrames ( queue , visitor , state )
52+ update ( frame , queue , visitor , clientRefVisitor )
53+ return flushFrames ( queue , visitor , clientRefVisitor , state )
5054 } ,
5155 ( error : Error ) => {
5256 if ( ! frame . errorFrame ) throw error
5357 frame . errorFrame . error = error
54- update ( frame . errorFrame , queue , visitor )
58+ update ( frame . errorFrame , queue , visitor , clientRefVisitor )
5559 }
5660 )
5761}
5862
5963const defaultVisitor = ( ) => undefined
6064
61- const renderPrepass = ( element : Node , visitor ? : Visitor ) : Promise < void > => {
65+ declare var globalThis: any
66+
67+ let runningPrepassCount = 0
68+
69+ const renderPrepass = (
70+ element : Node ,
71+ visitor ? : Visitor ,
72+ clientRefVisitor ? : ClientReferenceVisitor
73+ ) : Promise < void > => {
6274 if ( ! visitor ) visitor = defaultVisitor
75+ if ( ! clientRefVisitor ) clientRefVisitor = defaultVisitor
6376
6477 const queue : Frame [ ] = [ ]
6578 // Renderer state is kept globally but restored and
@@ -74,12 +87,23 @@ const renderPrepass = (element: Node, visitor?: Visitor): Promise<void> => {
7487 setCurrentErrorFrame ( null )
7588
7689 try {
77- visit ( getChildrenArray ( element ) , queue , visitor )
90+ runningPrepassCount ++
91+ globalThis . __ssrPrepassEnv = { readContextValue, setContextValue }
92+ visit ( getChildrenArray ( element ) , queue , visitor , clientRefVisitor )
7893 } catch ( error ) {
94+ runningPrepassCount --
95+ if ( ! runningPrepassCount ) {
96+ delete globalThis . __ssrPrepassEnv
97+ }
7998 return Promise . reject ( error )
8099 }
81100
82- return flushFrames ( queue , visitor , state )
101+ return flushFrames ( queue , visitor , clientRefVisitor , state ) . finally ( ( ) => {
102+ runningPrepassCount --
103+ if ( ! runningPrepassCount ) {
104+ delete globalThis . __ssrPrepassEnv
105+ }
106+ } )
83107}
84108
85109export default renderPrepass
0 commit comments