Skip to content

Instantly share code, notes, and snippets.

@amir-ba
Forked from albe/ndjson.js
Created November 18, 2022 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amir-ba/43845f7cdcb3c532e3921aa6aedebcc7 to your computer and use it in GitHub Desktop.
Save amir-ba/43845f7cdcb3c532e3921aa6aedebcc7 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