Repository navigation
fix: v10 in depth review hotfixes - #1920
Merged
Merged
Conversation
isekovanic
requested review from
MartinCupela,
oliverlaz and
szuperaz
as code owners
October 19, 2026 21:39
6 tasks
MartinCupela
self-requested a review
October 20, 2026 09:18
MartinCupela
approved these changes
Oct 20, 2026
isekovanic
pushed a commit
that referenced
this pull request
Oct 20, 2026
## CLA - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required). - [ ] Code changes are tested ## Description of the changes, What, Why and How? **Stacked on #1920:** this PR targets `fix/v10-hotfixes` and should merge after #1920. Against that base it is comment-only; against `release-v10` its diff also shows #1920's changes until #1920 lands. **What:** Rewrites the comments and JSDoc in `src` (excluding the generated `src/gen`) and updates `JSDOC.md`. 134 `.ts` files change, and comment lines drop from about 11.4k to 6.3k. **Why:** The v10 refactorings left long, partly outdated comment prose: how things used to behave, review ids, method lists that restate signatures, and boilerplate repeated per class. Comments now describe the code as it is, only where it is not obvious. Comments that no longer matched the code were corrected, several of them predating this PR. **How:** Comment-only. Compiled output is identical for every file apart from comments (each file was transpiled with comments removed, before and after, and compared). Exported public API keeps a summary plus `@param`/`@returns`; internals are documented in prose. Prose uses `ID` casing and `Defaults to X.`. `JSDOC.md` gains a public API vs internals section and the content rules this PR follows. `TODO`/`FIXME` lines, lint directives and commented-out code are untouched. `yarn lint`, `yarn types` and `yarn test` pass. **Reviewing:** The diff is large and mostly deletions. The useful feedback is any comment that is still wrong, and any "why" that should have stayed. ## Changelog - Tidy comments and JSDoc in `src`. No behaviour change. --------- Co-authored-by: martincupela <martin.cupela@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
github-actions Bot
pushed a commit
that referenced
this pull request
Oct 20, 2026
## [10.0.0-rc.23](v10.0.0-rc.22...v10.0.0-rc.23) (2026-10-20) ### Bug Fixes * add docs snippets; fix open api issues ([#1913](#1913)) ([53505e7](53505e7)) * address code issues found while reviewing v10 source comments ([#1922](#1922)) ([2fc319e](2fc319e)) * v10 in depth review hotfixes ([#1920](#1920)) ([98a298d](98a298d))
|
🎉 This PR is included in version 10.0.0-rc.23 🎉 The release is available on: Your semantic-release bot 📦🚀 |
isekovanic
added a commit
to GetStream/stream-chat-react-native
that referenced
this pull request
Oct 20, 2026
## 🎯 Goal Adapts the SDK to the signature changes in [GetStream/stream-chat-js#<PR>](GetStream/stream-chat-js#1920), the stream-chat v10 prerelease fixes. The other fixes in that PR need no change here as RN already reads typing from `channel.state` and the rest are LLC-internal. ## 🛠 Implementation details - `useCreateMessageActionHandlers` calls `client.pinMessage(message)`; it passed `null` before, which was the default anyway. It also calls `client.moderation.flagMessage({ message_id: message.id })`. (0d7953e) - `useChannelActions` calls `channel.addMembers({ members })` and `channel.removeMembers({ members })`. (0d7953e) - The 12 `pollComposer.updateFields(...)` calls in `components/Poll` pass `{ data: ... }`. (dcbb7f6) This needs the stream-chat release that contains the stream-chat-js PR. Until `stream-chat` is bumped, `yarn test:typecheck` fails on these call sites, because the installed rc still has the old signatures. ## 🎨 UI Changes / ## 🧪 Testing / ## ☑️ Checklist - [ ] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required) - [ ] PR targets the `develop` branch - [ ] Documentation is updated - [ ] New code is tested in main example apps, including all possible scenarios - [ ] SampleApp iOS and Android - [ ] Expo iOS and Android
isekovanic
pushed a commit
that referenced
this pull request
Oct 20, 2026
## Breaking changes - The `_request` placeholders are back Reverts/fixes some open-api related hotfixes from here: #1920 1. the `_request` placeholders are put back We need them, reasoning here: #1896 2. The `created_at*` type issues are solved by regenerating from the latest API spec, instead of manipulating the generated code 3. Disallowing `client('*')` This is done by excluding the `*` type from the hand-written `Event` type, rather than manipulating the generated `WSEvent` type
1 of 2 tasks
2 tasks done
oliverlaz
added a commit
that referenced
this pull request
Oct 29, 2026
Ticket: https://linear.app/stream/issue/REACT-1466 ## CLA - [x] I have signed the [Stream CLA](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) (required). - [x] Code changes are tested ## Description of the changes, What, Why and How? In v10 `Event` is a discriminated union, but `channel.state.typing` was still typed `Record<string, Event>`. Any custom typing indicator that reads `event.user` or `event.parent_id` stopped compiling and needed a hand-written `(e): e is EventPayload<'typing.start'> => e.type === 'typing.start'` guard. Found while migrating the stream-chat-react demo apps to v15 rc (stream-chat 10.0.0-rc.26). Only `typing.start` events are ever stored in that slice. The one writer is the `typing.start` case in `Channel._handleChannelEvent` (guarded on `event.user?.id`), `typing.stop` only removes an entry, and `clean()` only reads `received_at`. So the type is narrowed to match what is stored: - `TypingUsersState.typing` (and so `ChannelStateData['typing']`), the `channel.state.typing` setter and `setTypingEvent` now use `Record<string, EventPayload<'typing.start'>>` / `EventPayload<'typing.start'>`. No new exported alias. - New compile-time test `test/types/typing-state.ts` (runs in `yarn types` and `types:dist`): `Object.values(channel.state.typing)[0].user?.id` and `.parent_id` compile with no guard, the slice type is pinned, and passing a `typing.stop` to `setTypingEvent` is rejected. Against the old types it fails with 6 errors. `ai-docs/v10-breaking-changes.md`: - §7 (`ChannelState` is a `StateStore<ChannelStateData>`): the parenthetical said stream-chat-react's `TypingIndicator` "reads the composer copy", which contradicted the same sentence (`channel.state` is the only owner) and the React v15 guide. It now says the indicator reads `channel.state`, and documents the narrowed type. - §18: dropped the "`TextComposerState.typing` added as required" entry and the `typing` / `setTyping` / `setTypingEvent` / `removeTypingEvent` members from the `TextComposer` row of the added-members table. That composer copy was removed in #1920, so both described an API that no longer exists and contradicted §7. Compatibility: this is narrower than before, so code that assigned non-`typing.start` events into `channel.state.typing` or `setTypingEvent` no longer compiles. Nothing in the SDK does that, and readers only gain. ### Test results - `yarn types`: pass (includes `types:scripts` and `types:tests`) - `yarn lint`: clean, zero warnings - `yarn test`: 135 files, 4820 tests passed ## Changelog - `channel.state.typing` and `ChannelState.setTypingEvent` are typed as `typing.start` events, so `event.user` reads without a type guard.
github-actions Bot
pushed a commit
that referenced
this pull request
Oct 30, 2026
## [10.0.0-rc.27](v10.0.0-rc.26...v10.0.0-rc.27) (2026-10-30) ### Bug Fixes * consolidate master and v10 ([#1957](#1957)) ([802a956](802a956)) * handle tokenProvider rejection during reconnect token refresh ([#1963](#1963)) ([e22d218](e22d218)) * narrow channel.state.typing to typing.start events ([#1960](#1960)) ([acb2345](acb2345)), closes [#1920](#1920) * odd edge cases for channel list recovery ([#1966](#1966)) ([dbc2468](dbc2468)) * pass full request options to hydration query ([#1959](#1959)) ([489774b](489774b)) ### Features * regenerate from latest api spec; docs sync ([#1969](#1969)) ([ae1e86a](ae1e86a))
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.
CLA
Description of the changes, What, Why and How?
Fixes the "must fix" of the issues in section 1 of
ai-docs/v10-followups.md. Each item is its own commit, linked below. Two parts of that list are not in this PR: thechannel.query()message-set parameter is being fixed separately and the breaking removals listed at the end of section 1 get their own PR (probably tomorrow).Behaviour fixes
clear(), edit init, snapshot restore), because the text composer kept its own copy of the typing map. The copy is gone andchannel.stateis the only owner. Thread typing indicators that read the thread composer's copy, which was always empty, work once they readchannel.state. (f97ddd8)RetryErrorwith nocodeorstatus, and offline operations queued it as transient. The last attempt's error is rethrown instead, so callers get theStreamAPIError. A 429 is no longer retried, as in v9; it used to hold the caller for about 100 s. (e295664)show_in_channelreplies, so the channel list kept the old text unless aThreadfor the parent was held. The channel applies them now, and leaves them to the thread whenclient.threadsroutes the edit to a held one, so each collection still publishes once. (dd1b8c7)user.messages.deletedonly processed the active window, so after a jump to an older message the banned user's newest messages stayed visible. Every loaded interval is processed now. (45290f4)connectionRecovery.recover()did nothing whenconnectionRecovery.enabledwasfalse. The flag now only switches off the automatic recovery on reconnect, andrecover()always runs. With recovery disabled,connection.recoveredis still not dispatched on reconnect, since it means a recovery finished; the JSDoc says so now. (311c28a)items: undefinedon every load more, because the page cursor was part of the query shape. The cursor is applied per request instead. (73a8775)lastQueryErrorwas published on every failed attempt, before the retries ran out, so React showed error toasts and RN flashed its error screen for a query that recovered. It is published once, after the last attempt. (9cc208f)messageSearchSortwas appended after a fixedcreated_at: -1, so[{ field: 'created_at', direction: 1 }]sent a contradictory duplicate key. It is merged the v9 way:created_atstays the primary key and takes the caller's direction. (e32c8d5)Type fixes
on('all', cb)typed the event asnever, while undeclared names (typos,connection.changed) compiled and never fired.'all'now gets the fullEventunion, andon()/off()accept only anEventType, so custom events are declared throughCustomEventTypes.off(type, handler)takesEventHandler<type>, so a typed handler can be removed again. (c103da0)client.on('*')type-checked but never fired. The spec's{ type: '*' } & CustomEventplaceholder is dropped from the generated event unions. (79477d2)created_at_*filters ofQueryMembersPayload,QueryBannedUsersPayloadandQueryFutureChannelBansPayloadwere typedTimestampNS, which the API rejects withTime.UnmarshalJSON: input is not a JSON string(checked against a live app). They areDate | stringnow, matching the spec'sdate-time. (202e690, which also rewrites thetime.tsnote from 8bc711c)The generated-model changes are made by
scripts/apply-custom-data-types.mtsand a newscripts/drop-placeholder-request-params.mts, both run bygenerate-client.sh, so a regen keeps them.Signature changes (breaking)
These are in be73434 unless noted:
client.pinMessage({ id }, { pin_expires?, pinned_at? })andclient.unpinMessage({ id })take the message (or{ id }) and absolute dates. The relative-seconds number and the bare id string are gone.client.getThreadAndHydrate({ message_id }, options?), likegetThread.channel.addMembers,inviteMembersandremoveMemberstake{ members, message?, ...options };addFilterTagsandremoveFilterTagstake{ tags, message?, ...options }.channel.deleteImage({ url })andchannel.deleteFile({ url }), like the client methods.client.polls.queryPolls(request?)takes the same request asclient.queryPolls.client.moderation.flagMessage({ message_id, reason?, ...options })andflagUser({ user_id, reason?, ...options }).PollComposer.updateFields({ data, injectedFieldErrors? }). (4f8f95c)_request?: Record<string, never>parameter, sorequestOptionsfollows the path params directly (channel.pin({ signal }),client.getApp(requestOptions?)). (51fa769)Every change is recorded in
ai-docs/v10-breaking-changes.mdwith a migration line. The docs snippet tests use the new signatures; the matching getstream.io pages still need updating, andyarn test-docs-syncreports those regions until they are.Testing
Each fix comes with unit or type tests that fail on the previous code.
yarn test,yarn types,yarn lintandyarn types-docspass. The two unhandled rejections the suite reports (fromoptimisticRouting.test.tsandpoll.test.js) predate this branch.Changelog
channel.stateowns the typing map (f97ddd8)on('all')gets the fullEventtype;on()/off()accept only declared event names (c103da0)'*'placeholder from the event types (79477d2)show_in_channelreplies to the channel list (dd1b8c7)user.messages.deletedprocesses every loaded message (45290f4)connectionRecovery.recover()works when automatic recovery is disabled (311c28a)lastQueryErroronly after the retries run out (9cc208f)messageSearchSortundercreated_atlike v9 (e32c8d5)Date | string(202e690)pinMessage,getThreadAndHydrate, channel member and filter-tag helpers,channel.deleteImage/deleteFile,polls.queryPolls,flagMessage/flagUser(be73434)PollComposer.updateFieldstakes one object (4f8f95c)