refactor(server-renderer): adjust streaming API
- add `pipeToNodeWritable` - add `pipeToWebWritable`
This commit is contained in:
@@ -24,10 +24,10 @@ import {
|
||||
} from 'vue'
|
||||
import { escapeHtml } from '@vue/shared'
|
||||
import { renderToString } from '../src/renderToString'
|
||||
import { renderToNodeStream } from '../src/renderToStream'
|
||||
import { renderToNodeStream, pipeToNodeWritable } from '../src/renderToStream'
|
||||
import { ssrRenderSlot, SSRSlot } from '../src/helpers/ssrRenderSlot'
|
||||
import { ssrRenderComponent } from '../src/helpers/ssrRenderComponent'
|
||||
import { Readable } from 'stream'
|
||||
import { Readable, Transform } from 'stream'
|
||||
import { ssrRenderVNode } from '../src'
|
||||
|
||||
const promisifyStream = (stream: Readable) => {
|
||||
@@ -45,12 +45,25 @@ const promisifyStream = (stream: Readable) => {
|
||||
})
|
||||
}
|
||||
|
||||
const renderToStream = (app: any, context?: any) =>
|
||||
promisifyStream(renderToNodeStream(app, context))
|
||||
const renderToStream = (app: any, context?: any) => {
|
||||
return promisifyStream(renderToNodeStream(app, context))
|
||||
}
|
||||
|
||||
const pipeToWritable = (app: any, context?: any) => {
|
||||
const stream = new Transform({
|
||||
transform(data, _encoding, cb) {
|
||||
this.push(data)
|
||||
cb()
|
||||
}
|
||||
})
|
||||
pipeToNodeWritable(app, context, stream)
|
||||
return promisifyStream(stream)
|
||||
}
|
||||
|
||||
// we run the same tests twice, once for renderToString, once for renderToStream
|
||||
testRender(`renderToString`, renderToString)
|
||||
testRender(`renderToStream`, renderToStream)
|
||||
testRender(`renderToNodeStream`, renderToStream)
|
||||
testRender(`pipeToNodeWritable`, pipeToWritable)
|
||||
|
||||
function testRender(type: string, render: typeof renderToString) {
|
||||
describe(`ssr: ${type}`, () => {
|
||||
@@ -760,7 +773,7 @@ function testRender(type: string, render: typeof renderToString) {
|
||||
test('handle compiler errors', async () => {
|
||||
await render(
|
||||
// render different content since compilation is cached
|
||||
createApp({ template: `<${type === 'renderToString' ? 'div' : 'p'}` })
|
||||
createApp({ template: `<div>${type}</` })
|
||||
)
|
||||
|
||||
expect(
|
||||
|
||||
@@ -3,10 +3,19 @@
|
||||
*/
|
||||
|
||||
import { createApp, h, defineAsyncComponent } from 'vue'
|
||||
import { ReadableStream } from 'stream/web'
|
||||
import { renderToWebStream } from '../src'
|
||||
import { ReadableStream, TransformStream } from 'stream/web'
|
||||
import { pipeToWebWritable, renderToWebStream } from '../src'
|
||||
|
||||
test('should work', async () => {
|
||||
beforeEach(() => {
|
||||
global.ReadableStream = ReadableStream
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// @ts-ignore
|
||||
delete global.ReadableStream
|
||||
})
|
||||
|
||||
test('renderToWebStream', async () => {
|
||||
const Async = defineAsyncComponent(() =>
|
||||
Promise.resolve({
|
||||
render: () => h('div', 'async')
|
||||
@@ -16,14 +25,42 @@ test('should work', async () => {
|
||||
render: () => [h('div', 'parent'), h(Async)]
|
||||
}
|
||||
|
||||
const stream = renderToWebStream(createApp(App), {}, ReadableStream)
|
||||
const stream = renderToWebStream(createApp(App))
|
||||
|
||||
const reader = stream.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
|
||||
let res = ''
|
||||
await reader.read().then(function read({ done, value }): any {
|
||||
if (!done) {
|
||||
res += value
|
||||
res += decoder.decode(value)
|
||||
return reader.read().then(read)
|
||||
}
|
||||
})
|
||||
|
||||
expect(res).toBe(`<!--[--><div>parent</div><div>async</div><!--]-->`)
|
||||
})
|
||||
|
||||
test('pipeToWebWritable', async () => {
|
||||
const Async = defineAsyncComponent(() =>
|
||||
Promise.resolve({
|
||||
render: () => h('div', 'async')
|
||||
})
|
||||
)
|
||||
const App = {
|
||||
render: () => [h('div', 'parent'), h(Async)]
|
||||
}
|
||||
|
||||
const { readable, writable } = new TransformStream()
|
||||
pipeToWebWritable(createApp(App), {}, writable)
|
||||
|
||||
const reader = readable.getReader()
|
||||
const decoder = new TextDecoder()
|
||||
|
||||
let res = ''
|
||||
await reader.read().then(function read({ done, value }): any {
|
||||
if (!done) {
|
||||
res += decoder.decode(value)
|
||||
return reader.read().then(read)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user