wip(ssr): improve buffer typing
This commit is contained in:
parent
78beed2574
commit
8857b4f288
@ -10,8 +10,14 @@ import {
|
|||||||
} from 'vue'
|
} from 'vue'
|
||||||
import { isString, isPromise, isArray, isFunction } from '@vue/shared'
|
import { isString, isPromise, isArray, isFunction } from '@vue/shared'
|
||||||
|
|
||||||
|
// Each component has a buffer array.
|
||||||
|
// A buffer array can contain one of the following:
|
||||||
|
// - plain string
|
||||||
|
// - A resolved buffer (recursive arrays of strings that can be unrolled
|
||||||
|
// synchronously)
|
||||||
|
// - An async buffer (a Promise that resolves to a resolved buffer)
|
||||||
type SSRBuffer = SSRBufferItem[]
|
type SSRBuffer = SSRBufferItem[]
|
||||||
type SSRBufferItem = string | ResolvedSSRBuffer | Promise<SSRBuffer>
|
type SSRBufferItem = string | ResolvedSSRBuffer | Promise<ResolvedSSRBuffer>
|
||||||
type ResolvedSSRBuffer = (string | ResolvedSSRBuffer)[]
|
type ResolvedSSRBuffer = (string | ResolvedSSRBuffer)[]
|
||||||
|
|
||||||
function createBuffer() {
|
function createBuffer() {
|
||||||
@ -53,10 +59,7 @@ function unrollBuffer(buffer: ResolvedSSRBuffer): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function renderToString(app: App): Promise<string> {
|
export async function renderToString(app: App): Promise<string> {
|
||||||
const resolvedBuffer = (await renderComponent(
|
const resolvedBuffer = await renderComponent(app._component, app._props)
|
||||||
app._component,
|
|
||||||
app._props
|
|
||||||
)) as ResolvedSSRBuffer
|
|
||||||
return unrollBuffer(resolvedBuffer)
|
return unrollBuffer(resolvedBuffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +68,7 @@ export function renderComponent(
|
|||||||
props: Record<string, any> | null = null,
|
props: Record<string, any> | null = null,
|
||||||
children: VNode['children'] = null,
|
children: VNode['children'] = null,
|
||||||
parentComponent: ComponentInternalInstance | null = null
|
parentComponent: ComponentInternalInstance | null = null
|
||||||
): ResolvedSSRBuffer | Promise<SSRBuffer> {
|
): ResolvedSSRBuffer | Promise<ResolvedSSRBuffer> {
|
||||||
const vnode = createVNode(comp, props, children)
|
const vnode = createVNode(comp, props, children)
|
||||||
const instance = createComponentInstance(vnode, parentComponent)
|
const instance = createComponentInstance(vnode, parentComponent)
|
||||||
const res = setupComponent(instance, null)
|
const res = setupComponent(instance, null)
|
||||||
@ -79,7 +82,7 @@ export function renderComponent(
|
|||||||
function innerRenderComponent(
|
function innerRenderComponent(
|
||||||
comp: Component,
|
comp: Component,
|
||||||
instance: ComponentInternalInstance
|
instance: ComponentInternalInstance
|
||||||
): ResolvedSSRBuffer | Promise<SSRBuffer> {
|
): ResolvedSSRBuffer | Promise<ResolvedSSRBuffer> {
|
||||||
const { buffer, push, hasAsync } = createBuffer()
|
const { buffer, push, hasAsync } = createBuffer()
|
||||||
if (isFunction(comp)) {
|
if (isFunction(comp)) {
|
||||||
renderVNode(push, renderComponentRoot(instance))
|
renderVNode(push, renderComponentRoot(instance))
|
||||||
@ -101,10 +104,7 @@ function innerRenderComponent(
|
|||||||
// If the current component's buffer contains any Promise from async children,
|
// If the current component's buffer contains any Promise from async children,
|
||||||
// then it must return a Promise too. Otherwise this is a component that
|
// then it must return a Promise too. Otherwise this is a component that
|
||||||
// contains only sync children so we can avoid the async book-keeping overhead.
|
// contains only sync children so we can avoid the async book-keeping overhead.
|
||||||
return hasAsync()
|
return hasAsync() ? Promise.all(buffer) : (buffer as ResolvedSSRBuffer)
|
||||||
? // TS can't figure out the typing due to recursive appearance of Promise
|
|
||||||
Promise.all(buffer as any)
|
|
||||||
: (buffer as ResolvedSSRBuffer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderVNode(push: (item: SSRBufferItem) => void, vnode: VNode) {
|
export function renderVNode(push: (item: SSRBufferItem) => void, vnode: VNode) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user