|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function postWithSSE(url, body, callbacks) { |
|
const { onMessage, onError } = callbacks; |
|
|
|
try { |
|
const response = await fetch(url, { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
'Accept': 'text/event-stream' |
|
}, |
|
body: JSON.stringify(body), |
|
}); |
|
|
|
if (!response.ok) { |
|
throw new Error(`HTTP error! status: ${response.status}`); |
|
} |
|
|
|
if (!response.body) { |
|
throw new Error('Response body is null.'); |
|
} |
|
|
|
const reader = response.body.getReader(); |
|
const decoder = new TextDecoder(); |
|
let buffer = ''; |
|
|
|
while (true) { |
|
const { value, done } = await reader.read(); |
|
|
|
|
|
|
|
const chunk = decoder.decode(value, { stream: true }); |
|
buffer += chunk; |
|
|
|
|
|
|
|
|
|
let boundary; |
|
while ((boundary = buffer.indexOf('\n\n')) !== -1) { |
|
const messageString = buffer.substring(0, boundary); |
|
buffer = buffer.substring(boundary + 2); |
|
|
|
|
|
if (messageString.trim() === '') { |
|
continue; |
|
} |
|
|
|
|
|
|
|
if (messageString.startsWith('data:')) { |
|
const jsonData = messageString.substring('data: '.length); |
|
try { |
|
const parsedData = JSON.parse(jsonData); |
|
if (parsedData.status === "complete") |
|
return parsedData; |
|
else |
|
onMessage(parsedData); |
|
} catch (e) { |
|
console.error("Failed to parse JSON from SSE message:", jsonData, e); |
|
|
|
if (onError) onError(new Error("Failed to parse JSON from SSE message.")); |
|
} |
|
} |
|
} |
|
} |
|
} catch (error) { |
|
throw error; |
|
} |
|
} |