66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
export async function request(url, data, method = "POST") {
|
|
try {
|
|
const res = await fetch(url, {
|
|
method,
|
|
credentials: "same-origin",
|
|
headers: {"Content-Type": "application/json"},
|
|
body: data ? JSON.stringify(data) : undefined
|
|
});
|
|
return await res.json();
|
|
} catch {
|
|
return {error: "Network error - please try again."};
|
|
}
|
|
}
|
|
|
|
export const get = (url) => request(url, null, "GET");
|
|
export const post = (url, data) => request(url, data, "POST");
|
|
export const put = (url, data) => request(url, data, "PUT");
|
|
export const del = (url) => request(url, null, "DELETE");
|
|
|
|
export async function stream(url, data, handlers = {}) {
|
|
const response = await fetch(url, {
|
|
method: "POST",
|
|
credentials: "same-origin",
|
|
headers: {"Content-Type": "application/json"},
|
|
body: JSON.stringify(data || {})
|
|
});
|
|
|
|
if (!response.ok || !response.body) {
|
|
let error = "Streaming request failed";
|
|
try {
|
|
const payload = await response.json();
|
|
error = payload.error || error;
|
|
} catch {
|
|
// Keep the generic error if the server did not send JSON.
|
|
}
|
|
if (handlers.onError) {
|
|
handlers.onError({error});
|
|
return;
|
|
}
|
|
throw new Error(error);
|
|
}
|
|
|
|
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 parts = buffer.split("\n\n");
|
|
buffer = parts.pop() || "";
|
|
for (const part of parts) {
|
|
const lines = part.split("\n");
|
|
const eventLine = lines.find((line) => line.startsWith("event:"));
|
|
const dataLine = lines.find((line) => line.startsWith("data:"));
|
|
if (!eventLine || !dataLine) continue;
|
|
const event = eventLine.slice(6).trim();
|
|
const payload = JSON.parse(dataLine.slice(5).trim());
|
|
if (event === "chunk" && handlers.onChunk) handlers.onChunk(payload);
|
|
if (event === "done" && handlers.onDone) handlers.onDone(payload);
|
|
if (event === "error" && handlers.onError) handlers.onError(payload);
|
|
}
|
|
}
|
|
}
|