Skip to content

Fix reset aircraft clearing, console history drafts, log-stream rendering and 3D model fallback - #177

Merged
amorfinv merged 5 commits into
mainfrom
fix/reset-clearing-and-frontend-defects
Aug 15, 2026
Merged

Fix reset aircraft clearing, console history drafts, log-stream rendering and 3D model fallback#177
amorfinv merged 5 commits into
mainfrom
fix/reset-clearing-and-frontend-defects

Conversation

@amorfinv

Copy link
Copy Markdown
Collaborator

Five independent defects, one commit each.

fix(proxy): clear aircraft on the RESET topic, not on an ACDATA action

BlueSky signals a simulation reset on the dedicated RESET topic, but the clear lived in on_acdata_received, keyed off a context action that bluesky_client synthesised from the shared-state wrapper. That mapping made the ACDATA path clear traffic on frames it should only have forwarded, while a real RESET left proxy.traffic_data populated.

  • bluesky_client records the wire action verbatim and hands handlers the unwrapped data dict.
  • on_reset_received clears the cached traffic and emits an empty acdata alongside the existing poly/polyline clears, still scoped to the active node. It clears even with no browser attached — on_acdata_received only refreshes the cache while clients are connected, so a stale cache would be served verbatim in the next initial_data snapshot (ghost aircraft on the next page load).
  • node_manager drops the previous node's cached traffic on an active-node switch, so it can't be re-served before the new node's first frame.

fix(console): keep the unsubmitted draft across history navigation

ArrowUp discarded whatever was typed on the fresh input line, and ArrowDown back past the newest entry restored '' instead of it — a half-written command was lost by glancing at history. CommandHistory now stashes the draft like a shell. Also skips consecutive duplicates on add() and folds the two arrow-key branches in Console into one navigateHistory().

fix(log-stream): render split lines whole and ignore stale poll responses

The tail endpoint returns raw bytes, so a poll can land mid-line and the remainder arrives in the next chunk — one log line rendered as two. The trailing fragment is now buffered and re-rendered in place. Plus: in-flight fetches resolving after stopStreaming() or a file switch appended the old stream's content and clobbered the offset (fixed with a generation counter); a backwards offset now replaces the display instead of appending under the old content; Ctrl+F only opened search on lowercase f.

fix(aircraft-3d): fall back to the default model when a GLB fails to load

A model that 404s or fails to parse left its aircraft queued in pendingAircraft forever — invisible in 3D — and the loader re-requested the broken path on every data tick, since only loadingModels was cleared on error. The loader now records failed paths and reports them; redirectPending() re-creates stranded aircraft with the fallback model or drops them with a warning. Failures clear with the cache so a model reload retries.

chore: drop comments that restate the code

Docblocks that repeat the method name, in the files touched above.

Note

frontend/package-lock.json has an unrelated local change (removal of libc metadata from optional platform deps, an npm-version artifact) and is not part of this branch — it is still uncommitted locally.

🤖 Generated with Claude Code

amorfinv and others added 5 commits August 15, 2026 08:14
BlueSky signals a simulation reset on the dedicated RESET topic, but the
clear lived in on_acdata_received, keyed off a context action that the
client synthesised from the shared-state wrapper. That mapping made the
ACDATA path clear traffic on frames it should only have forwarded, while
a real RESET left proxy.traffic_data populated.

- bluesky_client: stop rewriting the wire action into Reset/ActChange;
  record it verbatim and hand handlers the unwrapped data dict.
- events.on_reset_received: clear the cached traffic and emit an empty
  acdata alongside the existing poly/polyline clears, still scoped to the
  active node. The cache is cleared even with no browser attached, since
  on_acdata_received only refreshes it while clients are connected and a
  stale cache would be served verbatim in the next initial_data snapshot.
- node_manager: drop the previous node's cached traffic when the active
  node changes, so it can't be re-served before the new node's first frame.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ArrowUp discarded whatever was typed on the fresh input line, and
ArrowDown back past the newest entry restored an empty string instead of
it, so a half-written command was lost by glancing at history. Shells
stash the draft; CommandHistory now does too.

Also skip consecutive duplicate entries on add(), reset navigation on
submit, and fold the two near-identical arrow-key branches in Console
into one navigateHistory() call that passes the current input through.

Console.historyNav.test.ts drives the real keydown handler end to end so
the round trip is pinned at the DOM level, not just on the model.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nses

The tail endpoint returns raw bytes, so a poll can land mid-line and the
remainder arrives in the next chunk — one log line rendered as two. The
trailing fragment is now buffered and re-rendered in place as later
chunks extend it.

Two related defects on the same path:
- An in-flight fetch that resolved after stopStreaming() or a switch to
  another file appended the old stream's content and clobbered the
  offset. A generation counter now discards those responses.
- A backwards offset means the file was truncated or rewritten, so the
  display is replaced instead of appending the new content under the old.
- Ctrl+F only opened search on lowercase 'f' (missed with Shift/CapsLock).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…load

A model that 404s or fails to parse left its aircraft queued in
pendingAircraft forever — invisible in 3D — and the loader re-requested
the broken path on every data tick, since only loadingModels was cleared
on error.

The loader now records failed paths, skips re-requesting them, and
reports the failure. Aircraft3DFleet.redirectPending() re-creates the
stranded aircraft with the fallback model (queueing again if it hasn't
loaded yet) or drops them with a warning when there is no fallback.
Aircraft3DCustomLayer also substitutes the fallback at resolve time, so
the path stays stable across ticks and the mesh isn't rebuilt.

Failures are recorded under the same teardown guard as the success
callback and cleared with the cache, so a model reload retries them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removes docblocks and inline comments that only repeat the method name
("Initialize header component", "Set scale") in the files touched by the
preceding fixes, and inlines a single-use matrix variable in
Aircraft3DTransforms.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@amorfinv
amorfinv merged commit 916e2cc into main Aug 15, 2026
2 checks passed
@amorfinv
amorfinv deleted the fix/reset-clearing-and-frontend-defects branch August 15, 2026 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant