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