| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- /* @flow */
- /**
- * Original RenderStream implementation by Sasha Aickin (@aickin)
- * Licensed under the Apache License, Version 2.0
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Modified by Evan You (@yyx990803)
- */
- const stream = require('stream')
- import { isTrue, isUndef } from 'shared/util'
- import { createWriteFunction } from './write'
- export default class RenderStream extends stream.Readable {
- buffer: string;
- render: (write: Function, done: Function) => void;
- expectedSize: number;
- write: Function;
- next: Function;
- end: Function;
- done: boolean;
- constructor (render: Function) {
- super()
- this.buffer = ''
- this.render = render
- this.expectedSize = 0
- this.write = createWriteFunction((text, next) => {
- const n = this.expectedSize
- this.buffer += text
- if (this.buffer.length >= n) {
- this.next = next
- this.pushBySize(n)
- return true // we will decide when to call next
- }
- return false
- }, err => {
- this.emit('error', err)
- })
- this.end = () => {
- this.emit('beforeEnd')
- // the rendering is finished; we should push out the last of the buffer.
- this.done = true
- this.push(this.buffer)
- }
- }
- pushBySize (n: number) {
- const bufferToPush = this.buffer.substring(0, n)
- this.buffer = this.buffer.substring(n)
- this.push(bufferToPush)
- }
- tryRender () {
- try {
- this.render(this.write, this.end)
- } catch (e) {
- this.emit('error', e)
- }
- }
- tryNext () {
- try {
- this.next()
- } catch (e) {
- this.emit('error', e)
- }
- }
- _read (n: number) {
- this.expectedSize = n
- // it's possible that the last chunk added bumped the buffer up to > 2 * n,
- // which means we will need to go through multiple read calls to drain it
- // down to < n.
- if (isTrue(this.done)) {
- this.push(null)
- return
- }
- if (this.buffer.length >= n) {
- this.pushBySize(n)
- return
- }
- if (isUndef(this.next)) {
- // start the rendering chain.
- this.tryRender()
- } else {
- // continue with the rendering.
- this.tryNext()
- }
- }
- }
|