Skip to content

chore(realtime)!: mark the transport internals @internal - #1674

Open
spydon wants to merge 4 commits into
chore/register-remaining-symbolsfrom
chore/internal-realtime-transport
Open

chore(realtime)!: mark the transport internals @internal#1674
spydon wants to merge 4 commits into
chore/register-remaining-symbolsfrom
chore/internal-realtime-transport

Conversation

@spydon

@spydon spydon commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Stacked on #1673. Follow-up to the audit in that PR: of the 536 entries in the top-level supporting_symbols list, ten were realtime transport internals that had no business being public in the first place. They were registered there for want of a better home, which was the wrong answer.

What becomes @internal

Symbol What it is
RealtimeClient.sendBuffer Queue of callbacks awaiting a connection
RealtimeClient.stateChangeCallbacks The open/close/error/message listener registry behind onOpen and friends
RealtimeClient.ref Message ref counter
RealtimeClient.makeRef Increments the counter, handling overflow
RealtimeClient.push Raw frame send
RealtimeClient.heartbeatTimer The Timer driving heartbeats
RealtimeClient.pendingHeartbeatRef Ref of the last unacknowledged heartbeat
RealtimeClient.reconnectTimer The RetryTimer behind reconnect backoff
RealtimeChannel.canPush Whether the socket is connected and the channel joined
RealtimeChannel.trigger Dispatches a raw event to the channel's bindings

push is the clearest case: it already took Message, which #1671 marked @internal, so it could not be called from outside the package regardless. Its signature said internal while its name said public.

The rest are fields on a class that happens to be public, so Dart's underscore rule made them public by default. None appears in any documented flow. Every one of them has a public counterpart that is the supported way in: onOpen/onClose/onError/onMessage instead of stateChangeCallbacks, heartbeatIntervalMs instead of heartbeatTimer, reconnectAfterMs instead of reconnectTimer, sendBroadcastMessage instead of push.

Matrix changes

Ten symbols leave the scan, so they leave sdk-compliance.yaml too:

  • Eight drop out of the top-level supporting_symbols list.
  • RealtimeClient.reconnectTimer drops from realtime.configuration.reconnect_backoff, and heartbeatTimer/pendingHeartbeatRef from realtime.configuration.heartbeat_interval. Both features keep their real evidence (reconnectAfterMs, heartbeatIntervalMs), and reconnect_backoff no longer needs a supporting_symbols list at all.

Public surface 1774 → 1764. Coverage stays at 100%.

Breaking

Marked chore(realtime)! with a BREAKING CHANGE footer. It is a genuine public API removal, though the practical risk is low: none of these is documented, push was already uncallable, and v3 is the right window. Anyone reaching for them was working around a missing public API, which is worth an issue rather than a lint suppression.

Test plan

  • dart analyze packages/: No issues found. This is the gate that matters here: invalid_use_of_internal_member fires for any cross-package use, and the supabase and supabase_flutter packages both consume RealtimeClient and RealtimeChannel. Neither touches any of the ten.
  • realtime_client tests: 205 passed. @internal permits same-package use, so the existing tests that drive makeRef, push and trigger still compile and run.
  • supabase tests: 134 passed, including the realtime stream integration tests.
  • supabase_flutter tests: 65 passed.
  • check-drift: ✅ No capability matrix drift detected.
  • check-api-symbols against chore: register the remaining public API in the capability matrix #1673 as base: ✅ All new public API symbols are covered in the capability matrix. This is the check that would have caught a stale registration, since the ten removed symbols were all registered on the base.
  • Uncovered symbol count from a fresh extraction: 0.
  • dart format packages/: 0 changed.

RealtimeClient and RealtimeChannel exposed ten members that exist only to
drive the websocket, not to be called: the send buffer and its state change
callback registry, the message ref counter and its generator, the heartbeat
and reconnect timers, the pending heartbeat ref, the raw push, and the
channel's canPush and trigger.

push already took Message, which is @internal, so it could not be called
from outside the package regardless. The rest were public only because they
are fields on a class that is itself public.

Drops them from the capability matrix, where the backfill had registered
them in the top-level supporting_symbols list for want of a better home.

BREAKING CHANGE: RealtimeClient.sendBuffer, stateChangeCallbacks, ref,
makeRef, push, heartbeatTimer, reconnectTimer and pendingHeartbeatRef, and
RealtimeChannel.canPush and trigger, are no longer part of the public API.
@spydon
spydon requested a review from a team as a code owner August 7, 2026 15:24
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 039a1ded-16a4-462d-87f3-80ea39cb50ba

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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