Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788export class ReaderApiError extends Error { constructor(status, message) { super(message); this.status = status; }}
export async function api(url, options = {}) { const response = await fetch("/api/reader" + url, { ...options, headers: { ...(options.body && !(options.body instanceof FormData) ? { "Content-Type": "application/json" } : {}), ...options.headers, }, body: options.body && !(options.body instanceof FormData) ? JSON.stringify(options.body) : options.body, }); if (!response.ok) { const payload = await response.json().catch(() => ({})); throw new ReaderApiError(response.status, payload.error || `Request failed (${response.status}).`); } return response.status === 204 ? null : response.json();}
export async function streamChat(chatId, input, signal, onEvent) { return streamOperation(`/chats/${chatId}/send`, input, signal, onEvent);}
export async function streamOperation(path, input, signal, onEvent) { const response = await fetch(`/api/reader${path}`, { method: "POST", signal, headers: { "Content-Type": "application/json" }, body: JSON.stringify(input), }); if (!response.ok) throw new ReaderApiError(response.status, (await response.json().catch(() => ({}))).error || "Unable to start this request.", ); if (!response.body) throw new Error("The server did not return a response stream."); const reader = response.body.getReader(), decoder = new TextDecoder(); let buffer = ""; while (true) { const { done, value } = await reader.read(); if (done) break; buffer += decoder.decode(value, { stream: true }); buffer = buffer.replace(/\r\n/g, "\n"); let end; while ((end = buffer.indexOf("\n\n")) >= 0) { const frame = buffer.slice(0, end); buffer = buffer.slice(end + 2); for (const line of frame.split("\n")) if (line.startsWith("data: ")) onEvent(JSON.parse(line.slice(6))); } } buffer += decoder.decode(); for (const line of buffer.split("\n")) if (line.startsWith("data: ")) onEvent(JSON.parse(line.slice(6)));}export function downloadText(name, text, type = "text/markdown") { const url = URL.createObjectURL(new Blob([text], { type })), link = document.createElement("a"); link.href = url; link.download = name; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000);}export function readPreference(key, fallback) { try { return JSON.parse(localStorage.getItem("odre." + key)) ?? fallback; } catch { return fallback; }}export function savePreference(key, value) { try { localStorage.setItem("odre." + key, JSON.stringify(value)); } catch { /* local preference storage is optional */ }}