[reflex-xy] Make selection work with more than ten scatter traces

Open
#430 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
javascript, python

Research direction

Start with select_range() in python/xy/interaction.py and _selection_reply() in python/xy/channel.py, then trace on_msg in python/reflex_xy/namespace.py and the on_select_end dispatch in XYChart.jsx. Run the existing socket data-plane regression before adding a real 11-trace Socket.IO case and a browser callback test. Done means masks and canonical row IDs survive encoding, the callback fires, and replies stay within the attachment ceiling.

Written by the indexing model from the issue text.

Description

Summary

A normal box or lasso selection can generate more binary attachments than the Reflex Socket.IO transport permits. With eleven visible scatter traces, the selection reply contains eleven mask buffers, so the namespace rejects the reply and the client receives neither the selection mask nor on_select_end.

This is a user-visible protocol-shape defect, not a failure of the attachment guard: the guard correctly prevents an oversized packet from closing the app's shared websocket.

Audited at commit 99eda6d.

Current behavior

select_range() records every visible scatter trace, including traces with an empty selection. _selection_reply() then emits one u32 buffer per trace.

The Reflex namespace has a hard ten-attachment ceiling because Socket.IO's browser parser closes the shared websocket above it. on_msg therefore returns err instead of the selection reply. The wrapper only logs that error, so its on_select_end dispatch never runs.

A direct probe with eleven scatter traces produced eleven reply buffers. The existing transport regression describes channel replies as "bounded by construction" but only simulates an oversized reply with monkeypatching; it does not exercise a real multi-trace selection (test).

Proposed direction

Use a selection representation whose attachment count is independent of trace count. For example, concatenate all u32 masks into one binary attachment and carry per-trace offset/count metadata. Omitting empty masks can reduce work but should not be the only fix, because eleven non-empty traces must still work.

If the selection message shape changes, update/version the documented wire contract and keep drill_seq and trace identity explicit.

Acceptance criteria
  • Box and lasso selection work with at least 11 visible, non-empty scatter traces.
  • The selection mask reaches the chart and on_select_end fires with the expected total and per-trace canonical row IDs.
  • No selection reply emits more than the Socket.IO attachment ceiling, regardless of trace count.
  • Empty selections do not consume one attachment per trace.
  • Trace IDs, counts, drill_seq, and shipped-index semantics survive encoding/decoding exactly.
  • A real Socket.IO regression exercises an 11+ trace selection end-to-end; a browser test verifies mask application and callback delivery.
  • The wire protocol/design documentation is updated if the message representation changes.
Related, not duplicate

#385 closed the uncapped broadcast_message append-push path. This issue concerns a normal selection reply whose current first-party representation inherently exceeds the guarded limit.

Dominant language
Python
Stars
1.8k
Forks
76
Avg merge
1h 7m
Merged PRs (30d)
8

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from reflex-dev/xy

All issues in reflex-dev/xy

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.