Last active
December 1, 2022 04:10
-
-
Save NotWoods/39e1f7d29a56be0d012461cde409e285 to your computer and use it in GitHub Desktop.
Node.js - Break up a stream and reassemble it so that each line is a chunk.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const stream = require("stream"); | |
/** Simplified version of split() on npm. */ | |
const split = new stream.Transform({ | |
/** | |
* @param {Buffer | string} chunk is the data from the Readable Stream. | |
* @param {string} encoding is the file encoding, but isn't used here. | |
* @param {() => void} next is a callback function called when you finish working | |
* with this chunk. | |
*/ | |
transform(chunk, encoding, next) { | |
/* this.soFar represents the current line so far. | |
* First, this.soFar is replaced with "" if it is null or undefined. | |
* This happens with the first chunk and if Array.pop() is called | |
* on an empty array. | |
* Next, the soFar string is combined with the string provided by | |
* the stream ("chunk"). .toString() converts buffers to strings. | |
* Finally, the string is split at the newline character defined | |
* by the \r?\n RegEx. This RegEx translates to either | |
* "\r\n" or "\n", which are the two end of line characters used by | |
* Windows and Unix respectively. */ | |
const lines = ((this.soFar != null ? this.soFar: "") + chunk.toString()).split(/\r?\n/); | |
/* The last element of the array, aka data after the last complete line, | |
* is removed with Array.pop() and stored in this.soFar for future */ | |
this.soFar = lines.pop(); | |
/* Each complete line is sent as a seperate push. If no line is | |
* completed, this.push isn't called so nothing is outputted that time. */ | |
for (var line of lines) { this.push(line); } | |
/* next() indicates that operations on this chunk are done. */ | |
next(); | |
}, | |
/** | |
* If the file does not end in a newline, flush will output the | |
* remaining this.soFar data from the last line. | |
*/ | |
flush(done) { | |
/* Like the previous instance, this.soFar is | |
* replaced with "" if it is null or undefined. | |
* Then, it is pushed out. */ | |
this.push(this.soFar != null ? this.soFar:""); | |
/* done() indicates that operations are done. */ | |
done(); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment