From 44d29866e74335100d17e8d48bf9a42f86194d76 Mon Sep 17 00:00:00 2001 From: giles Date: Wed, 1 Jul 2026 20:31:44 +0000 Subject: [PATCH] otel: wire /otel into the SPA (dual-mode SX + sx-trigger poll refresh) --- lib/host/otel.sx | 21 ++++++++++++++------- lib/host/tests/otel.sx | 16 +++++++++++----- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/lib/host/otel.sx b/lib/host/otel.sx index 9f69e532..6fabdb2a 100644 --- a/lib/host/otel.sx +++ b/lib/host/otel.sx @@ -481,13 +481,13 @@ (traces (otel/recent-traces))) (quasiquote (div :id "otel-dashboard" - ;; The host serves single-body responses (no server-push SSE), so the - ;; dashboard stays live by reloading itself — every 3s it re-renders the - ;; latest metrics + trace. /otel/stream remains a snapshot of the newest - ;; span for any client that wants to poll it. - (meta :http-equiv "refresh" :content "3") + ;; SPA-native live refresh: the SX engine polls GET /otel every 3s and + ;; swaps this div in place (outerHTML). The poll is a boosted request, so + ;; the route returns the text/sx fragment — no full reload, stays in the + ;; SPA. (No , which would blow away the SPA shell.) + :sx-get "/otel" :sx-trigger "every 3s" :sx-target "#otel-dashboard" :sx-swap "outerHTML" (h1 "OpenTelemetry") - (p :style "font-size:0.8em;opacity:0.7" "live · auto-refreshes every 3s") + (p :style "font-size:0.8em;opacity:0.7" "live · refreshes every 3s in-app") (h2 "latency by route") (p :style "font-size:0.75em;opacity:0.7" (span :style "color:#4c9a8f" "▉ p50") " " @@ -505,9 +505,16 @@ (unquote (otel/-traces-list traces))))))) ;; ── routes ──────────────────────────────────────────────────────────── +;; Dual-mode, wired into the SPA: a boosted (SX-Request) fetch — a link click OR +;; the 3s poll — gets the dashboard as a text/sx fragment the WASM kernel renders +;; into place; a direct/no-JS load gets the full SPA shell (host/blog--page) with +;; the dashboard in #content, so it degrades to a plain server-rendered page. +;; (Reuses the host SPA shell + content-type negotiation from lib/host/blog.sx.) (define otel/dashboard-route (dream-get "/otel" - (fn (req) (dream-html (render-to-html (otel/dashboard) {}))))) + (fn (req) + (host/blog--resp req 200 + (host/blog--page req "OpenTelemetry" (otel/dashboard)))))) (define otel/stream-route (dream-get "/otel/stream" (fn (req) diff --git a/lib/host/tests/otel.sx b/lib/host/tests/otel.sx index 3897b249..cb8fea3e 100644 --- a/lib/host/tests/otel.sx +++ b/lib/host/tests/otel.sx @@ -234,7 +234,8 @@ (host-ot-test "dashboard has the root id" (contains? host-ot-dash "otel-dashboard") true) (host-ot-test "dashboard SSRs the waterfall svg" (contains? host-ot-dash "