69 lines
2.0 KiB
JavaScript
69 lines
2.0 KiB
JavaScript
// Web Worker for handling streaming response parsing
|
|
self.onmessage = async function(e) {
|
|
const { url, body } = e.data;
|
|
|
|
try {
|
|
const response = await fetch(url, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: body
|
|
});
|
|
|
|
if (!response.ok) {
|
|
let errorMessage = `请求失败 (${response.status})`;
|
|
try {
|
|
const data = await response.json();
|
|
if (data?.error) {
|
|
errorMessage = data.error;
|
|
}
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
self.postMessage({ type: 'error', message: errorMessage });
|
|
return;
|
|
}
|
|
|
|
if (!response.body) {
|
|
self.postMessage({ type: 'error', message: 'No response body' });
|
|
return;
|
|
}
|
|
|
|
const reader = response.body.getReader();
|
|
const decoder = new TextDecoder();
|
|
let buffer = '';
|
|
|
|
while (true) {
|
|
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) {
|
|
if (!line.trim()) continue;
|
|
|
|
try {
|
|
const message = JSON.parse(line);
|
|
self.postMessage({ type: 'message', message: message });
|
|
} catch (err) {
|
|
// ignore parse errors
|
|
}
|
|
}
|
|
}
|
|
|
|
if (buffer.trim()) {
|
|
try {
|
|
const message = JSON.parse(buffer);
|
|
self.postMessage({ type: 'message', message: message });
|
|
} catch (err) {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
self.postMessage({ type: 'complete' });
|
|
} catch (err) {
|
|
self.postMessage({ type: 'error', message: err.message });
|
|
}
|
|
};
|