Skip to content

Instantly share code, notes, and snippets.

@albe
Created July 3, 2018 15:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save albe/f7e7a43950eb3b068129342b5e79c951 to your computer and use it in GitHub Desktop.
Save albe/f7e7a43950eb3b068129342b5e79c951 to your computer and use it in GitHub Desktop.
ndjson fetch API transformer
const parseLine = (line) => {
try {
return JSON.parse(line);
} catch (e) {
}
};
const ucasefirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
/* A simple wrapper that will turn a fetch response into a streaming emitter of JSON objects
* Usage:
* fetch(URI).then(response => ndjson(response)
* .on('data', data => {
* ...
* })
* .on('error', err => {
* ...
* })
* .on('end', () => {
* ...
* })
* })
*/
const ndjson = (response) => {
const decoder = new TextDecoder();
const reader = response.body.getReader();
let buffer = '';
const streamer = reader.read().then(function process(result) {
if (result.done) {
if (buffer.length > 0) {
const result = parseLine(buffer);
streamer.onData([result]);
}
streamer.onEnd();
return;
}
buffer += decoder.decode(result.value, {stream: true});
const lines = buffer.split("\n");
buffer = lines.pop();
const results = lines.filter(line => line.trim().length > 0).map(parseLine);
if (results.length > 0) {
streamer.onData(results);
}
return reader.read().then(process);
}).catch((e) => {
streamer.onError(e);
reader.cancel();
streamer.onEnd();
});
streamer.onData = streamer.onError = streamer.onEnd = () => {};
streamer.on = (event, handler) => {
streamer['on' + ucasefirst(event)] = handler;
return streamer;
};
streamer.cancel = () => {
reader.cancel();
streamer.onEnd();
};
return streamer;
};
export default ndjson;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment