import { App , createApp , createVNode , ssrContextKey , ssrUtils , VNode } from 'vue' ; import { isPromise , isString } from '@vue/shared' ; import { SSRContext , renderComponentVNode , SSRBuffer } from './render' ; const { isVNode } = ssrUtils ; async function unrollBuffer ( buffer ) { if ( buffer . hasAsync ) { let ret = '' ; for ( let i = 0 ; i < buffer . length ; i ++ ) { let item = buffer [ i ] ; if ( isPromise ( item ) ) { item = await item ; } if ( isString ( item ) ) { ret += item ; } else { ret += await unrollBuffer ( item ) ; } } return ret ; } else { return unrollBufferSync ( buffer ) ; } } function unrollBufferSync ( buffer ) { let ret = '' ; for ( let i = 0 ; i < buffer . length ; i ++ ) { let item = buffer [ i ] ; if ( isString ( item ) ) { ret += item ; } else { ret += unrollBufferSync ( item as SSRBuffer ) ; } } return ret ; } export async function renderToString ( input , context = { } ) { if ( isVNode ( input ) ) { return renderToString ( createApp ( { render : ( ) => input } ) , context ) ; } const vnode = createVNode ( input . _component , input . _props ) ; vnode . appContext = input . _context ; input . provide ( ssrContextKey , context ) ; const buffer = await renderComponentVNode ( vnode ) ; await resolveTeleports ( context ) ; return unrollBuffer ( buffer as SSRBuffer ) ; } async function resolveTeleports ( context ) { if ( context . __teleportBuffers ) { context . teleports = context . teleports || { } ; for ( const key in context . __teleportBuffers ) { context . teleports [ key ] = await unrollBuffer ( ( await Promise . all ( context . __teleportBuffers [ key ] ) ) as SSRBuffer ) ; } } }