(() => { const modal = document.querySelector("[data-debug-modal]"); const openButton = document.querySelector("[data-debug-open]"); const closeButton = modal?.querySelector("[data-debug-close]"); const status = modal?.querySelector("[data-debug-status]"); const page = modal?.querySelector("[data-debug-page]"); const slider = modal?.querySelector("[data-debug-slider]"); const previous = modal?.querySelector("[data-debug-prev]"); const next = modal?.querySelector("[data-debug-next]"); const summary = modal?.querySelector("[data-debug-summary]"); const json = modal?.querySelector("[data-debug-json]"); const items = []; let current = -1; let sessionId = null; let source = null; const render = () => { const total = items.length; if (!total) { current = -1; page.textContent = "0 / 0"; slider.min = "1"; slider.max = "1"; slider.value = "1"; slider.disabled = true; previous.disabled = true; next.disabled = true; summary.textContent = "No payloads received during this session."; json.textContent = "{}"; return; } current = Math.max(0, Math.min(current, total - 1)); const item = items[current]; page.textContent = `${current + 1} / ${total}`; slider.min = "1"; slider.max = String(total); slider.value = String(current + 1); slider.disabled = false; previous.disabled = current === 0; next.disabled = current === total - 1; summary.innerHTML = ""; [ `Endpoint: ${item.endpointIdentifier}`, `Event: ${item.eventType || "unknown"}`, `Event ID: ${item.eventId || "none"}`, `Authenticity: ${item.authentic ? "valid" : item.authenticityStatus}` ].forEach((text) => { const line = document.createElement("div"); line.textContent = text; summary.appendChild(line); }); json.textContent = JSON.stringify(item.payload || { raw_body_preview: item.rawBodyPreview }, null, 2); }; const stop = async () => { source?.close(); source = null; if (sessionId) { navigator.sendBeacon?.(`/plugins/throne_wishlist/debug/stop/${sessionId}`); sessionId = null; } }; const close = async () => { await stop(); modal.classList.remove("is-open"); modal.setAttribute("aria-hidden", "true"); }; const open = async () => { items.length = 0; current = -1; render(); modal.classList.add("is-open"); modal.setAttribute("aria-hidden", "false"); status.textContent = "Starting debug session…"; try { const response = await fetch("/plugins/throne_wishlist/debug/start", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" } }); if (!response.ok) throw new Error("Unable to start debug session."); const data = await response.json(); sessionId = data.sessionId; source = new EventSource(`/plugins/throne_wishlist/debug/stream/${sessionId}`); source.addEventListener("ready", () => { status.textContent = "Listening for new Throne payloads."; }); source.addEventListener("payload", (event) => { items.push(JSON.parse(event.data)); current = items.length - 1; status.textContent = "Payload received."; render(); }); source.addEventListener("close", (event) => { const data = JSON.parse(event.data || "{}"); status.textContent = `Debug session ended: ${data.reason || "closed"}.`; source?.close(); }); source.onerror = () => { status.textContent = "Debug stream disconnected."; }; } catch (error) { status.textContent = error.message; } }; openButton?.addEventListener("click", open); closeButton?.addEventListener("click", close); modal?.addEventListener("click", (event) => { if (event.target === modal) close(); }); previous?.addEventListener("click", () => { current -= 1; render(); }); next?.addEventListener("click", () => { current += 1; render(); }); slider?.addEventListener("input", () => { current = Number(slider.value) - 1; render(); }); window.addEventListener("keydown", (event) => { if (event.key === "Escape" && modal?.classList.contains("is-open")) close(); }); window.addEventListener("beforeunload", stop); })();