feat!: receive parallels send — Client::onMessage delivers the default transport only - #23
Merged
Merged
Conversation
… parallels send) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Client::onMessagenow fires only for messages arriving on the default transport — the receive-side mirror ofClient::send(doc)routing to the default transport only. The guard is evaluated per dispatch, so a runtimesetDefaultTransport()switch takes effect immediately.defaultTransport = nullnow closes the default lane in both directions.onText/onBinary/MQTT's topic-awareonMessage), which become the receive path for non-default transports.UdpTransport::onText(cb)— raw per-packet receive hook, same idiom asWebSocketTransport::onText(UDP previously had no per-transport receive path).Why
One rule in both directions: the default transport is the client-level lane; everything else is per-transport. This removes the aggregate-dispatch ambiguity that made multi-transport consumers filter by transport name, and it lets topic-aware consumers (e.g. MQTT topic routing in downstream layers) own their delivery without double-dispatch through the client callback. Groundwork for channel-based routing in Resident/Hawthorn (which needs MQTT consumed via its topic hook only).
Migration
Multi-transport users who relied on
onMessagereceiving all transports' messages should register per-transport hooks for the non-default transports (orsetDefaultTransportto the lane they want at the client level). Downstream: Resident ≥0.7 defaultsdefaultTransportto"ws"when unset and a host is configured.Tests
test_client(default-only dispatch, per-transport hook delivery on non-default transports, runtime default switch, null-default closed lane); 4 pre-existing tests adapted to the new contract (no assertions weakened)../tools/run-tests.py unit: 163/163 pass; static-analysis clean.🤖 Generated with Claude Code