File size: 1,126 Bytes
a63c2c0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
 * Read the NDJSON progress stream the generation routes return.
 *
 * Lines arrive as {"type":"status"|"result"|"error"}. A chunk can split a line
 * anywhere, so the tail is held back until its newline shows up.
 */
export async function readJobStream(body:ReadableStream<Uint8Array>,
 on:{status?:(text:string)=>void;result?:(value:unknown)=>void}){
 const reader=body.getReader(),decoder=new TextDecoder();
 let buffer='',result:unknown=null,failure='';
 const take=(line:string)=>{
  if(!line.trim())return;
  let event:{type?:string;data?:unknown};
  try{event=JSON.parse(line);}catch{return;}
  if(event.type==='status'&&typeof event.data==='string')on.status?.(event.data);
  if(event.type==='error')failure=String(event.data||'Generation failed.');
  if(event.type==='result'){result=event.data;on.result?.(event.data);}
 };
 for(;;){
  const {value,done}=await reader.read();
  if(done)break;
  buffer+=decoder.decode(value,{stream:true});
  const lines=buffer.split('\n');
  buffer=lines.pop()||'';
  for(const line of lines)take(line);
 }
 take(buffer);
 if(failure)throw new Error(failure);
 return result;
}