Last active
April 17, 2025 11:21
-
-
Save ornicar/a097406810939cf7be1df8ea30e94f3e to your computer and use it in GitHub Desktop.
Read a ND-JSON stream from the browser or from nodejs
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
/* FOR THE BROWSER | |
Utility function to read a ND-JSON HTTP stream. | |
`processLine` is a function taking a JSON object. It will be called with each element of the stream. | |
`response` is the result of a `fetch` request. | |
See usage example in the next file. | |
*/ | |
const readStream = processLine => response => { | |
const stream = response.body.getReader(); | |
const matcher = /\r?\n/; | |
const decoder = new TextDecoder(); | |
let buf = ''; | |
const loop = () => | |
stream.read().then(({ done, value }) => { | |
if (done) { | |
if (buf.length > 0) processLine(JSON.parse(buf)); | |
} else { | |
const chunk = decoder.decode(value, { | |
stream: true | |
}); | |
buf += chunk; | |
const parts = buf.split(matcher); | |
buf = parts.pop(); | |
for (const i of parts.filter(p => p)) processLine(JSON.parse(i)); | |
return loop(); | |
} | |
}); | |
return loop(); | |
} |
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
/* FOR NODEJS | |
Utility function to read a ND-JSON HTTP stream. | |
`processLine` is a function taking a JSON object. It will be called with each element of the stream. | |
`response` is the result of a `fetch` request. | |
See usage example in the next file. | |
*/ | |
const readStream = processLine => response => { | |
const matcher = /\r?\n/; | |
const decoder = new TextDecoder(); | |
let buf = ''; | |
return new Promise((resolve, fail) => { | |
response.body.on('data', v => { | |
const chunk = decoder.decode(v, { stream: true }); | |
buf += chunk; | |
const parts = buf.split(matcher); | |
buf = parts.pop(); | |
for (const i of parts.filter(p => p)) processLine(JSON.parse(i)); | |
}); | |
response.body.on('end', () => { | |
if (buf.length > 0) processLine(JSON.parse(buf)); | |
resolve(); | |
}); | |
response.body.on('error', fail); | |
}); | |
}; |
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
/* From browser or nodejs alike */ | |
const stream = fetch('https://lichess.org/api/tv/feed'); | |
// or any other ND-JSON endpoint such as: | |
// const stream = fetch('https://lichess.org/api/games/user/neio',{headers:{Accept:'application/x-ndjson'}}); | |
const onMessage = obj => console.log(obj); | |
const onComplete = () => console.log('The stream has completed'); | |
stream | |
.then(readStream(onMessage)) | |
.then(onComplete); |
Sure.
Install dependancies
npm install react-native-polyfill-globals text-encoding react-native-fetch-api web-streams-polyfill
MyComponentScreen.native.tsx
(polyfill are not needed/working for web)
import { polyfill as polyfillEncoding } from 'react-native-polyfill-globals/src/encoding';
import { polyfill as polyfillReadableStream } from 'react-native-polyfill-globals/src/readable-stream';
import { polyfill as polyfillFetch } from 'react-native-polyfill-globals/src/fetch';
polyfillEncoding();
polyfillReadableStream();
polyfillFetch();
[...]
const readStream = (processLine) => (response) => {
// same as browser-ndjson-stream-reader.js above
[...]
}
const stream = fetch(`https://lichess.org/api/board/game/stream/${gameId}`, {
reactNative: { textStreaming: true },
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`,
Accept: 'application/x-ndjson',
},
});
const onMessage = (obj) => console.log(obj);
const onComplete = () => console.log('The stream has completed');
stream
.then(readStream(onMessage))
.then(onComplete);
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @konpa Is it possible to make a little exemple of how did you done? It can be helpfull for begginers
Thanks!