[feat](trx-frontend-http): split decode history into separate HTTP endpoint

Move history replay out of the /decode SSE stream into a new
GET /decode/history JSON endpoint. The JS client now opens /decode
immediately for live packets (no gating) and fetches history in
parallel via fetch(), draining it in the background with the existing
chunked drainDecodeHistory() helper.

This ensures real-time decode messages are never blocked by a large
history payload, and removes the historyReceived gate entirely.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-10 18:33:40 +01:00
parent 5a3c013db5
commit 35983eb971
2 changed files with 71 additions and 65 deletions
@@ -6054,26 +6054,16 @@ function connectDecode() {
if (window.resetCwHistoryView) window.resetCwHistoryView();
if (window.resetFt8HistoryView) window.resetFt8HistoryView();
if (window.resetWsprHistoryView) window.resetWsprHistoryView();
// Live messages arrive after the history event; gate on this flag so
// onmessage does not dispatch before drainDecodeHistory has started.
let historyReceived = false;
// Open the live SSE stream first so real-time messages are never blocked by
// history replay. History is fetched separately via a plain HTTP request and
// drained in the background using the existing chunked helper.
decodeSource = new EventSource("/decode");
decodeSource.onopen = () => {
decodeConnected = true;
updateDecodeStatus("Connected, listening for packets");
};
// The server sends the entire history as one named "history" event (JSON
// array). A single JSON.parse + chunked drain is far cheaper than N
// individual EventSource callbacks each blocking the main thread.
decodeSource.addEventListener("history", (evt) => {
try {
const msgs = JSON.parse(evt.data);
if (Array.isArray(msgs)) drainDecodeHistory(msgs, 0);
} catch (e) { /* ignore parse errors */ }
historyReceived = true;
});
decodeSource.onmessage = (evt) => {
if (!historyReceived) return; // skip anything before history event
try {
dispatchDecodeMessage(JSON.parse(evt.data));
} catch (e) { /* ignore parse errors */ }
@@ -6091,6 +6081,14 @@ function connectDecode() {
setTimeout(connectDecode, 5000);
}
};
// Fetch history in parallel — does not block the live SSE stream.
fetch("/decode/history").then((resp) => {
if (!resp.ok) return;
return resp.json();
}).then((msgs) => {
if (Array.isArray(msgs)) drainDecodeHistory(msgs, 0);
}).catch(() => { /* history unavailable, ignore */ });
}
if (document.readyState === "complete") {
connectDecode();