Files
CodeNavigator/web/api.mjs
T
Andy Dixon 5816dea6b1 Add Go HTTP/SSE API server with embedded frontend
Implements the API routes (jobs, progress events, snapshots, search,
entities, source delivery with release) to net/http and serves the
static frontend from the same binary on the same origin.
2026-01-25 09:10:28 +00:00

36 lines
1.3 KiB
JavaScript

export function apiFetch(url, options = {}) {
const headers = new Headers(options.headers);
headers.set('ngrok-skip-browser-warning', 'true');
return fetch(url, { ...options, headers });
}
// Read SSE over fetch so progress requests can carry the same headers as JSON.
export async function* progressEvents(response) {
if (!response.ok || !response.body || !response.headers.get('content-type')?.includes('text/event-stream')) {
throw new Error('Could not connect to indexing progress.');
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '', event = '', data = [];
try {
while (true) {
const { value, done } = await reader.read();
buffer += decoder.decode(value, { stream: !done });
let end;
while ((end = buffer.indexOf('\n')) >= 0) {
const line = buffer.slice(0, end).replace(/\r$/, '');
buffer = buffer.slice(end + 1);
if (!line) {
if (event === 'progress' && data.length) yield JSON.parse(data.join('\n'));
event = ''; data = [];
} else if (line.startsWith('event:')) event = line.slice(6).trim();
else if (line.startsWith('data:')) data.push(line.slice(5).replace(/^ /, ''));
}
if (done) break;
}
} finally {
await reader.cancel().catch(() => {});
reader.releaseLock();
}
}