Show the Name servers check as it happens, and keep its results

The zone's Name servers tab no longer waits for the other servers before
showing: it lists each query as a dig command line with a waiting
counter, fills in the answers as they arrive, then shows the result with
the queries under "Queries sent". Results (serials and delegation) are
kept for 10 minutes so revisiting the tab is instant; "Check again" asks
anew, and a check keeps running when the tab is left.

GET /zones/{zone}/serials?stream=1 streams the queries as
newline-delimited JSON (nscheck.Checker.Watch); without it the endpoint
is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adamandClaude Opus 5.5 committed 2026-10-09 15:49:11 +00:00
1 parent d961cb8792
commit 020223d1a5
11 files changed
+364 -23

No files matched your search

+28
View File
@@ -73,6 +73,34 @@ async function call(method, path, opts) {
export const get = (path, query) => api("GET", path, { query });
// stream GETs a newline-delimited JSON response (?stream=1 endpoints) and
// calls onEvent with each value as it arrives. It resolves at the end.
export async function stream(path, query, onEvent) {
const q = new URLSearchParams(query || {});
const resp = await fetch("/api/v1" + path + (q.toString() ? "?" + q : ""), { headers: { "Accept": "application/x-ndjson" }, credentials: "same-origin" });
if (!resp.ok) {
const ct = resp.headers.get("Content-Type") || "";
const data = ct.includes("application/json") ? await resp.json() : await resp.text();
if (resp.status === 401) onUnauthorized();
throw new APIError(resp.status, data);
}
const reader = resp.body.getReader();
const dec = new TextDecoder();
let buf = "";
for (;;) {
const { value, done } = await reader.read();
if (value) buf += dec.decode(value, { stream: true });
let nl;
while ((nl = buf.indexOf("\n")) >= 0) {
const line = buf.slice(0, nl).trim();
buf = buf.slice(nl + 1);
if (line) onEvent(JSON.parse(line));
}
if (done) break;
}
if (buf.trim()) onEvent(JSON.parse(buf));
}
// draftQuery adds the draft changeset to a query, so reads show the
// configuration as it will be once the pending changes are applied.
export function draftQuery(query = {}) {