Pyramid web app for inspecting arborist Merkle trees over sharded SQLite: document roots, inclusion proofs, an interactive 3D Merkle lattice (six.js / WebGL with graceful fallback), audit-chain linkage, and a live SSE event stream. Generated artifacts (env/, vendored static/six/ bundles, demo databases) are gitignored and rebuilt via the Makefile (venv, six, init-db, serve).
39 lines
1.1 KiB
JavaScript
39 lines
1.1 KiB
JavaScript
// Hash-drop dispatcher. Paste any hex hash, hit Enter, navigate.
|
|
|
|
export function wireHashDrop(form) {
|
|
if (!form) return;
|
|
const input = form.querySelector("#hash-input");
|
|
const status = form.querySelector("#hash-resolve-status");
|
|
|
|
form.addEventListener("submit", async (ev) => {
|
|
ev.preventDefault();
|
|
const h = (input.value || "").trim().toLowerCase();
|
|
if (!/^[0-9a-f]{4,128}$/.test(h)) {
|
|
setStatus(status, "not hex", "err");
|
|
return;
|
|
}
|
|
setStatus(status, "resolving…", "wait");
|
|
try {
|
|
const res = await fetch(`/api/resolve/${h}`);
|
|
const body = await res.json();
|
|
if (body.error === "no_shard") {
|
|
setStatus(status, "no shard configured", "err");
|
|
return;
|
|
}
|
|
if (body.kind === "unknown") {
|
|
setStatus(status, "not in any shard", "err");
|
|
return;
|
|
}
|
|
setStatus(status, `${body.kind} →`, "ok");
|
|
window.location.href = body.url;
|
|
} catch (err) {
|
|
setStatus(status, `error: ${err.message}`, "err");
|
|
}
|
|
});
|
|
}
|
|
|
|
function setStatus(el, text, level) {
|
|
if (!el) return;
|
|
el.textContent = text;
|
|
el.dataset.level = level;
|
|
}
|