tweak render stream implementation

This commit is contained in:
Evan You 2016-05-08 18:11:19 -04:00
parent 8172e7e257
commit 097bb2e4e8

View File

@ -1,6 +1,6 @@
import stream from 'stream' import stream from 'stream'
const MAX_STACK_DEPTH = 500 const MAX_STACK_DEPTH = 1000
/** /**
* Original RenderStream implmentation by Sasha Aickin (@aickin) * Original RenderStream implmentation by Sasha Aickin (@aickin)
@ -12,35 +12,14 @@ export default class RenderStream extends stream.Readable {
super() super()
this.buffer = '' this.buffer = ''
this.render = render this.render = render
} this.expectedSize = 0
_read (n) { this.write = (text, next) => {
let bufferToPush const n = this.expectedSize
// 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 (this.done) {
this.push(null)
return
}
if (this.buffer.length >= n) {
bufferToPush = this.buffer.substring(0, n)
this.buffer = this.buffer.substring(n)
this.push(bufferToPush)
return
}
if (!this.next) {
this.stackDepth = 0
// start the rendering chain.
this.render(
// write
(text, next) => {
this.buffer += text this.buffer += text
if (this.buffer.length >= n) { if (this.buffer.length >= n) {
this.next = next this.next = next
bufferToPush = this.buffer.substring(0, n) this.pushBySize(n)
this.buffer = this.buffer.substring(n)
this.push(bufferToPush)
} else { } else {
// continue rendering until we have enough text to call this.push(). // continue rendering until we have enough text to call this.push().
// sometimes do this as process.nextTick to get out of stack overflows. // sometimes do this as process.nextTick to get out of stack overflows.
@ -52,13 +31,38 @@ export default class RenderStream extends stream.Readable {
this.stackDepth-- this.stackDepth--
} }
} }
}, }
// done
() => { this.end = () => {
// the rendering is finished; we should push out the last of the buffer. // the rendering is finished; we should push out the last of the buffer.
this.done = true this.done = true
this.push(this.buffer) this.push(this.buffer)
}) }
}
pushBySize (n) {
const bufferToPush = this.buffer.substring(0, n)
this.buffer = this.buffer.substring(n)
this.push(bufferToPush)
}
_read (n) {
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 (this.done) {
this.push(null)
return
}
if (this.buffer.length >= n) {
this.pushBySize(n)
return
}
if (!this.next) {
this.stackDepth = 0
// start the rendering chain.
this.render(this.write, this.end)
} else { } else {
// continue with the rendering. // continue with the rendering.
this.next() this.next()