Skip to content

Instantly share code, notes, and snippets.

@hikaMaeng
Created May 21, 2024 03:36
Show Gist options
  • Save hikaMaeng/7d46e62b0952ddf478194e16cb48437c to your computer and use it in GitHub Desktop.
Save hikaMaeng/7d46e62b0952ddf478194e16cb48437c to your computer and use it in GitHub Desktop.
const fetchStream = async (request)=>{
const controller = new AbortController();
try {
const option = {
method:request.method,
mode:request.mode,
credentials: 'include',
signal:controller.signal
};
if(request.headers) option.headers = request.headers;
if(request.body){
let chunkSize = 1024;
const body = new ReadableStream({
start(controller){
let i = 0, j = request.body.length;
const f = _=>{
if(controller.desiredSize <= 0){
chunkSize /= 2;
requestAnimationFrame(f);
return;
}
const start = i;
const end = i + chunkSize;
controller.enqueue(request.body.subarray(start, end <= j ? end : j));
request.onProgress?.(i, j);
if(end <= j){
i = end;
if(chunkSize < 1024 * 1024) chunkSize *= 2;
requestAnimationFrame(f);
}else{
controller.close();
}
}
f();
}
});
option.body = request.body;
}
const response = await fetch(request.url, option);
const reader = response.body.getReader();
let result = [];
let {done, value} = await reader.read();
const listener = request.type === 'CHUNK_TEXT' ? request.onText : request.onBlob;
while(!done){
const v = request.type === 'CHUNK_TEXT' ? Kore.decoder.decode(value) : value;
result.push(v);
if(!listener(v)){
controller.abort();
return;
}
({done, value} = await reader.read());
}
request.onComplete?.(result);
return result;
}catch(e){
if(e.name !== "AbortError") request.onError?.(e.message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment