-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathline-buffer.js
67 lines (52 loc) · 1.52 KB
/
line-buffer.js
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
/*
This module splits an incoming text stream by newline \n, and buffers
text without a newline until an additional newline comes along, or on
before the stream is closed.
*/
const Emitter = require('events')
const { Transform } = require('stream')
const EOL = '\n'
class LineBuffer extends Transform {
constructor () {
super({
// Split streaming text into single line chunks
transform: (chunk, enc, done) => {
const str = this.buf + chunk.toString()
this.buf = ''
const parts = str.split(/\r?\n/)
// Emit lines one by one
while (parts.length > 1) {
const line = parts.shift()
this.push(line + EOL)
}
// Buffer text that doesn't have an EOL.
// The first item of the array may be empty, which is okay.
this.buf += parts[0]
done(null)
},
// Empty the buffer before closing stream
flush: (done) => {
this.push(this.buf + EOL)
this.buf = ''
done(null)
}
})
// Initialise an empty buffer
this.buf = ''
// TODO: Move to a test instead. Doesn't need to be here.
this.on('end', () => {
if (this.buf.length) {
console.error('Stream ended with text still in buffer')
}
})
}
}
module.exports = LineBuffer
// TEST
if (!module.parent) {
const lb = new LineBuffer()
lb.pipe(process.stdout)
lb.write('first line\nsecond line\nand some text with no newline')
lb.write(', but here the newline comes\n')
lb.end('last and end\n\n')
}