Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 16x 503x 330x 173x 173x 302x 302x 121x 121x 181x 81x 79x 79x 100x 100x 22x 22x 22x 78x 199x 302x 497x 497x 599x 599x 432x 167x 497x 334x 43x 291x 291x 291x 291x 287x 285x 285x 3x 3x 285x 394x 15x 15x 15x | import {
type App,
type VNode,
createApp,
createVNode,
ssrContextKey,
ssrUtils,
} from '@vue/runtime-dom'
import { isPromise, isString } from '@vue/shared'
import { type SSRBuffer, type SSRContext, renderComponentVNode } from './render'
const { isVNode } = ssrUtils
function nestedUnrollBuffer(
buffer: SSRBuffer,
parentRet: string,
startIndex: number,
): Promise<string> | string {
if (!buffer.hasAsync) {
return parentRet + unrollBufferSync(buffer)
}
let ret = parentRet
for (let i = startIndex; i < buffer.length; i += 1) {
const item = buffer[i]
if (isString(item)) {
ret += item
continue
}
if (isPromise(item)) {
return item.then(nestedItem => {
buffer[i] = nestedItem
return nestedUnrollBuffer(buffer, ret, i)
})
}
const result = nestedUnrollBuffer(item, ret, 0)
if (isPromise(result)) {
return result.then(nestedItem => {
buffer[i] = nestedItem
return nestedUnrollBuffer(buffer, '', i)
})
}
ret = result
}
return ret
}
export function unrollBuffer(buffer: SSRBuffer): Promise<string> | string {
return nestedUnrollBuffer(buffer, '', 0)
}
function unrollBufferSync(buffer: SSRBuffer): string {
let ret = ''
for (let i = 0; i < buffer.length; i++) {
let item = buffer[i]
if (isString(item)) {
ret += item
} else {
// since this is a sync buffer, child buffers are never promises
ret += unrollBufferSync(item as SSRBuffer)
}
}
return ret
}
export async function renderToString(
input: App | VNode,
context: SSRContext = {},
): Promise<string> {
if (isVNode(input)) {
// raw vnode, wrap with app (for context)
return renderToString(createApp({ render: () => input }), context)
}
// rendering an app
const vnode = createVNode(input._component, input._props)
vnode.appContext = input._context
// provide the ssr context to the tree
input.provide(ssrContextKey, context)
const buffer = await renderComponentVNode(vnode)
const result = await unrollBuffer(buffer as SSRBuffer)
await resolveTeleports(context)
if (context.__watcherHandles) {
for (const unwatch of context.__watcherHandles) {
unwatch()
}
}
return result
}
export async function resolveTeleports(context: SSRContext): Promise<void> {
if (context.__teleportBuffers) {
context.teleports = context.teleports || {}
for (const key in context.__teleportBuffers) {
// note: it's OK to await sequentially here because the Promises were
// created eagerly in parallel.
context.teleports[key] = await unrollBuffer(
context.__teleportBuffers[key],
)
}
}
}
|