[fix](trx-frontend-http): restore decode history from the stored records
CI / lint (pull_request) Successful in 2m21s
CI / test (pull_request) Successful in 8m19s
CI / frontend (pull_request) Successful in 3m1s
CI / reuse (pull_request) Successful in 2s
CI / lint (push) Successful in 2m16s
CI / test (push) Successful in 7m26s
CI / frontend (push) Successful in 2m11s
CI / reuse (push) Successful in 2s

Replay required every restored record to carry a string `type`, and
stored records do not have one: an AIS entry holds mmsi, lat, lon,
crc_ok and its decoder's own fields, nothing more.  The filter therefore
discarded all of them, and did it silently — the fetch returned its full
payload, the worker decoded it, and no error was logged, so the history
simply never appeared.

That field identifies live SSE frames, which do carry it, which is why
only replay was affected.  History arrives already grouped and the
group's kind is delivered alongside the messages, so `type` was never
needed to route them.  Require only that a record is an object.

Confirmed against a live server: the first restored group is AIS, and
its records expose their decoder fields with `type` undefined.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GdyUjuXejCEfiub675z6cz
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit was merged in pull request #36.
This commit is contained in:
sjg
2026-08-03 18:39:13 +02:00
co-authored by Claude Opus 5
parent b252717f6b
commit 863a6d8fd4
2 changed files with 7 additions and 2 deletions
@@ -7424,7 +7424,7 @@ function connectDecode() {
return; return;
} }
if (data.type === "group") { if (data.type === "group") {
const messages = Array.isArray(data.messages) ? data.messages.filter((message) => isRecord2(message) && typeof message.type === "string") : []; const messages = Array.isArray(data.messages) ? data.messages.filter((message) => isRecord2(message)) : [];
enqueueDecodeHistoryGroup(typeof data.kind === "string" ? data.kind : "", messages); enqueueDecodeHistoryGroup(typeof data.kind === "string" ? data.kind : "", messages);
return; return;
} }
@@ -6366,7 +6366,12 @@ function connectDecode() {
} }
if (data.type === "group") { if (data.type === "group") {
const messages = Array.isArray(data.messages) const messages = Array.isArray(data.messages)
? data.messages.filter((message): message is DecodeMessage => isRecord(message) && typeof message.type === "string") // Stored records carry only decoder fields — an AIS entry has mmsi,
// lat, lon and so on, and no `type`. That field identifies live SSE
// frames; history is already grouped, and the group's kind is
// delivered alongside these messages, so requiring it here discarded
// every restored record silently.
? data.messages.filter((message): message is DecodeMessage => isRecord(message))
: []; : [];
enqueueDecodeHistoryGroup(typeof data.kind === "string" ? data.kind : "", messages); enqueueDecodeHistoryGroup(typeof data.kind === "string" ? data.kind : "", messages);
return; return;