@@ -14,6 +14,9 @@ import {
1414DIFF ,
1515DIFFED ,
1616DIRTY ,
17+ MODE_ASYNC ,
18+ MODE_STREAM ,
19+ MODE_SYNC ,
1720NEXT_STATE ,
1821PARENT ,
1922RENDER ,
@@ -79,7 +82,7 @@ export function renderToString(vnode, context) {
7982false ,
8083undefined ,
8184parent ,
82- false
85+ MODE_SYNC
8386) ;
8487} catch ( e ) {
8588if ( e . then ) {
@@ -92,14 +95,57 @@ export function renderToString(vnode, context) {
9295}
9396}
9497
95- const DEFAULT_RENDER_SLOT = ( idx ) =>
96- `<!--preact-slot:${ idx } --><!--/preact-slot:${ idx } -->` ;
98+ /**
99+ * Render Preact JSX + Components to an HTML string.
100+ *@param {VNode } vnodeJSX Element / VNode to render
101+ *@param {Object } [context={}] Initial root context object
102+ *@returns {Promise<string> } serialized HTML
103+ */
104+ export async function renderToStringAsync ( vnode , context ) {
105+ const previousSkipEffects = prepare ( ) ;
106+
107+ const parent = h ( Fragment , null ) ;
108+ parent [ CHILDREN ] = [ vnode ] ;
109+
110+ try {
111+ const rendered = _renderToString (
112+ vnode ,
113+ context || EMPTY_OBJ ,
114+ false ,
115+ undefined ,
116+ parent ,
117+ MODE_ASYNC
118+ ) ;
119+
120+ if ( Array . isArray ( rendered ) ) {
121+ let count = 0 ;
122+ let resolved = rendered ;
123+
124+ // Resolving nested Promises with a maximum depth of 25
125+ while (
126+ resolved . some ( ( element ) => typeof element . then === 'function' ) &&
127+ count ++ < 25
128+ ) {
129+ resolved = ( await Promise . all ( resolved ) ) . flat ( ) ;
130+ }
131+
132+ return resolved . join ( '' ) ;
133+ }
134+
135+ return rendered ;
136+ } finally {
137+ finalize ( vnode , previousSkipEffects ) ;
138+ }
139+ }
140+
141+ const DEFAULT_RENDER_SLOT = ( idx , content ) =>
142+ `<!--p:slot:${ idx } -->${ content } <!--/p:slot:${ idx } -->` ;
97143
98144/**
99145 * Render Preact JSX + Components to an HTML string.
100146 *@param {VNode } vnodeJSX Element / VNode to render
101147 *@param {Object } [context={}] Initial root context object
102- *@param {(idx: number) => string } [renderSlot] Render slot marker
148+ *@param {(idx: number, content: string ) => string } [renderSlot] Render slot marker
103149 *@returns {ReadableStream<string>|string } serialized HTML
104150 */
105151export function renderToStream (
@@ -119,7 +165,7 @@ export function renderToStream(
119165false ,
120166undefined ,
121167parent ,
122- true
168+ MODE_STREAM
123169) ;
124170
125171if ( Array . isArray ( rendered ) ) {
@@ -180,49 +226,6 @@ export function renderToStream(
180226}
181227}
182228
183- /**
184- * Render Preact JSX + Components to an HTML string.
185- *@param {VNode } vnodeJSX Element / VNode to render
186- *@param {Object } [context={}] Initial root context object
187- *@returns {Promise<string> } serialized HTML
188- */
189- export async function renderToStringAsync ( vnode , context ) {
190- const previousSkipEffects = prepare ( ) ;
191-
192- const parent = h ( Fragment , null ) ;
193- parent [ CHILDREN ] = [ vnode ] ;
194-
195- try {
196- const rendered = _renderToString (
197- vnode ,
198- context || EMPTY_OBJ ,
199- false ,
200- undefined ,
201- parent ,
202- true
203- ) ;
204-
205- if ( Array . isArray ( rendered ) ) {
206- let count = 0 ;
207- let resolved = rendered ;
208-
209- // Resolving nested Promises with a maximum depth of 25
210- while (
211- resolved . some ( ( element ) => typeof element . then === 'function' ) &&
212- count ++ < 25
213- ) {
214- resolved = ( await Promise . all ( resolved ) ) . flat ( ) ;
215- }
216-
217- return resolved . join ( '' ) ;
218- }
219-
220- return rendered ;
221- } finally {
222- finalize ( vnode , previousSkipEffects ) ;
223- }
224- }
225-
226229// Installed as setState/forceUpdate for function components
227230function markAsDirty ( ) {
228231this . __d = true ;
@@ -290,6 +293,7 @@ function renderClassComponent(vnode, context) {
290293 *@param {any } selectValue
291294 *@param {VNode } parent
292295 *@param {boolean } asyncMode
296+ *@param {number } renderMode
293297 *@returns {string | Promise<string> | (string | Promise<string>)[] }
294298 */
295299function _renderToString (
@@ -298,7 +302,7 @@ function _renderToString(
298302isSvgMode ,
299303selectValue ,
300304parent ,
301- asyncMode
305+ renderMode
302306) {
303307// Ignore non-rendered VNodes/values
304308if ( vnode == null || vnode === true || vnode === false || vnode === '' ) {
@@ -326,7 +330,7 @@ function _renderToString(
326330isSvgMode ,
327331selectValue ,
328332parent ,
329- asyncMode
333+ renderMode
330334) ;
331335
332336if ( typeof childRender === 'string' ) {
@@ -391,7 +395,7 @@ function _renderToString(
391395isSvgMode ,
392396selectValue ,
393397vnode ,
394- asyncMode
398+ renderMode
395399) ;
396400} else {
397401// Values are pre-escaped by the JSX transform
@@ -472,7 +476,7 @@ function _renderToString(
472476isSvgMode ,
473477selectValue ,
474478vnode ,
475- asyncMode
479+ renderMode
476480) ;
477481return str ;
478482} catch ( err ) {
@@ -504,7 +508,7 @@ function _renderToString(
504508isSvgMode ,
505509selectValue ,
506510vnode ,
507- asyncMode
511+ renderMode
508512) ;
509513}
510514
@@ -531,7 +535,7 @@ function _renderToString(
531535isSvgMode ,
532536selectValue ,
533537vnode ,
534- asyncMode
538+ renderMode
535539) ;
536540
537541try {
@@ -545,10 +549,11 @@ function _renderToString(
545549
546550return str ;
547551} catch ( error ) {
548- if ( ! asyncMode ) throw error ;
552+ if ( renderMode === MODE_SYNC ) throw error ;
549553
550554if ( ! error || typeof error . then !== 'function' ) throw error ;
551555
556+ console . log ( renderMode , error ) ;
552557const renderNestedChildren = ( ) => {
553558try {
554559return renderChildren ( ) ;
@@ -699,7 +704,7 @@ function _renderToString(
699704childSvgMode ,
700705selectValue ,
701706vnode ,
702- asyncMode
707+ renderMode
703708) ;
704709}
705710