refactor(client): centralize call leave reasons and align with Swift - #2231
refactor(client): centralize call leave reasons and align with Swift#2231oliverlaz wants to merge 4 commits into
Conversation
Replace ad-hoc leave-message strings with a centralized CallLeaveReasons table under `<source>:<reason>` kebab-case namespacing. Aligns the JS SDK with the Swift/Android reason vocabulary so cross-platform telemetry is consistent. - ring:* for ringing-lifecycle decisions (everyone-rejected, creator-rejected, timeout-creator, timeout-callee) - event:call-ended for backend call.ended - sfu:call-ended:<reason> built from the SFU code - device:accepted-elsewhere / device:rejected-elsewhere for the multi-device path driven by Call.registerEffects()'s session subscription Constants live in src/helpers/CallLeaveReasons.ts and are not re-exported from the package barrel: the message field on leave logs remains an internal SDK detail. No behavior change for public API consumers.
|
|
Warning Review limit reachedNext included review available in 49 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThe pull request consolidates call leave and rejection messages into standardized string constants. A new ChangesCall Leave Reason Constants
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Full details: Description checkExplanation The description includes the required Overview, Implementation notes, ticket, and Docs sections. It explains the implementation, scope, fixes, testing, and API impact. The Docs section explicitly states that documentation is not required. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Resolves two conflicts introduced while the branch was stale: - Call.ts ring-timeout: main reformatted the template literal, the branch replaced it with table constants. Kept the constants. - events/call.ts: main added `reason: 'ended'` to the `call.ended` leave and wrapped both backend-ended paths in `clientEventReporter.abort()`. Kept main's structure with the branch's constants. Also updates the `call.ended` test assertions for main's new `reason: 'ended'`.
The merge of main into this branch resolved Call.autodrop.test.ts by taking the branch version wholesale, which reverted main's change passing a ClientEventReporter into the test's Call constructor. The option is optional, so the suite stayed green and nothing flagged it.
Route every `call.leave({ message })` site and both matching
`clientEventReporter.abort()` reasons through a single `CallLeaveReasons`
table instead of scattered string literals.
The values stay as they are on main. The Swift SDK's
`StreamRejectionReasonProvider.HandledCallReason` already emits four of them
verbatim (`ring: creator rejected`, `ring: everyone rejected`,
`call.ended event received`, `user-responded-elsewhere`), so renaming them
would split backend analytics into two vocabularies for the same events.
Two genuine misalignments fixed along the way:
- The accepted/rejected-elsewhere path called `leave()` with no message at
all. It now sends `user-responded-elsewhere`, matching Swift. Swift uses a
single value covering accepted, rejected and missed elsewhere, so the two
device-specific values this branch previously proposed collapse into one.
- `ClientEventStandardCode` declared `NETWORK_ERROR` where Swift's
`ClientEventFailureCode` and Android's `AnalyticsCallAbortReason` both use
`NETWORK_OFFLINE`. Nothing ever emitted the code, so this is a
declaration-only rename.
Bundle sizeBuilt package output. Sizes in KB; delta vs
|
💡 Overview
Route every
call.leave({ message })site in the client through a single internalCallLeaveReasonstable instead of scattered string literals, and fix two places where the JS vocabulary had genuinely drifted from the Swift and Android SDKs.The direction of this PR changed since it was opened. It originally renamed the leave strings to a new
<source>:<reason>kebab-case scheme. In the meantime the Swift SDK adopted the existing JS strings verbatim in GetStream/stream-video-swift#1115 (merged 17 Apr 2026), soStreamRejectionReasonProvider.HandledCallReasonnow emitsring: creator rejected,ring: everyone rejectedandcall.ended event receivedexactly as this SDK does. Renaming them would break the only cross-SDK string alignment that exists and split backend analytics into two vocabularies for the same events. The table stays, the values do not change.📝 Implementation notes
packages/client/src/helpers/CallLeaveReasons.ts, 15 entries. Not re-exported from the package barrel: the leavemessageis an SDK-internal detail, verified absent fromdist/index.d.ts.user blocked,live ended,SFU instructed to disconnect,client.disconnectUser() called, the threegiveUpAndLeavereconnect reasons and theleaveReasonfallback. BothclientEventReporter.abort()reasons that were duplicating their leave message as a literal now read from the table too.Call.registerEffects()calledleave()with nomessageat all, so those leaves reported nothing. It now sendsuser-responded-elsewhere, matching Swift. Swift uses one value covering accepted, rejected and missed elsewhere, so the two device-specific values this branch originally proposed collapse into one. The existingStreamVideoClient.rewatchtest already covered this path; its assertion is tightened to lock the string.ClientEventStandardCodedeclaredNETWORK_ERRORwhere Swift'sClientEventFailureCodeand Android'sAnalyticsCallAbortReasonboth useNETWORK_OFFLINE. This code is on theretry_failure_codefield the backend groups on. Nothing ever emitted it, so this is a declaration-only rename with no runtime change.Full cross-SDK comparison of all 28 leave-message use cases, the failure codes and the wire enums: https://claude.ai/code/artifact/7d91310b-785b-4f0d-b4db-70498299aac9
Headline from that audit: the failure codes are a real shared contract and are in good shape after this PR. The leave messages are not a contract anywhere, and Swift is inconsistent with itself (its core layer matches JS, its SwiftUI
CallViewModelemits its ownblocked/unanswered/ended/auto-leave). Extending message alignment further needs a convention agreed with the iOS and Android teams rather than a unilateral rename from one platform, so this PR only preserves what already lines up.🎫 Ticket: https://linear.app/stream/issue/XYZ-123
📑 Docs: not required, no public API surface changes