Repository navigation
fix: v10 sdk regressions - #3916
Merged
Merged
Conversation
oliverlaz
approved these changes
Nov 2, 2026
Contributor
SDK Size
|
oliverlaz
added a commit
that referenced
this pull request
Nov 3, 2026
… against V10 (#3918) Ticket: https://linear.app/stream/issue/REACT-1307 ## Goal Make the v9 → v10 guide the input of a prebuilt migration prompt: a coding agent gets one URL plus the user's repo and has to migrate accurately. The guide had grown by accretion, which hurt that: - "Part I" and "§19" each appeared twice; - Verify sat in the middle of the guide; - K.8 came before K.6; - detection greps hard-coded `src/`; - there was history from release candidates, and many bug-fix sections with nothing for an integrator to do. ## Changes **`ai-docs/ai-migration-v9-to-v10.md`: structure** - The order is now: 1. Title and verified line 2. Rules (old §0 folded in) 3. Companion documents 4. Workflow, definition of done and report template 5. Detection (`rg -t js -t ts -g '!**/node_modules/**'`, keyed on v9 names) 6. Quick reference (20 rows added) 7. A consolidated "Breaks that compile" table (~40 rows, each with a Detect command) 8. Parts A–S 9. Verification, with a leftover-identifier grep 10. An index mapping every `v10-breaking-changes.md` section to a guide section - IDs: - Verify is now an unnumbered `## Verification`, so every existing `§19` reference (all of them mean i18n) stays valid. - The duplicate Part I (i18n) is now Part S. - K.x sections are in order. - Every § reference in `ai-docs/` resolves to a unique heading. - Sections with no integrator action are one-liners: L.8–L.10, M.1, M.3–M.5, M.7, P.10, P.14, P.16, P.18, P.19, P.21, P.22, Q.2. Their full text moved to section 17 of `v10-breaking-changes.md`. **Accuracy, re-verified at `74884ff55`** - #3916: a channel or thread reopened on an older page now jumps to the latest messages, and `useJumpToLatestOnOpen` is exported. Covered in §8, §R.5, the breaks table and the reference. - Wrong claim fixed: `<Chat>` does not replace an app's `statusReporter`; the app's reporter wins (§R.2). - Other fixes: - §16.3: capability gating; - `useMutedUsers()` returns `UserMuteResponse[]`; - the `typing` type; - `deleted_by` is removed; - `DEFAULT_BACKEND_SORT` is not exported; - a dead stream-chat-js link. - Names that only existed in release candidates are removed. Checked against the v9.11.1 / stream-chat 9.54.4 tags: - the `channel.state.*Store` handles and `mutedUsersStore`; - `WatcherState`, which was in §4's After snippet; - `MutedUsersState`, `normalizeTimestamp`, `getChannelUnreadState` and `*WithLocalUpdate`. - Remaining stale mentions fixed: `channel.deactivate()` and `client.activeChannels` in `channel-state-ui-migration.md`, and the `markRead` description in `v10-docs-impact.md`. - `ai-migration.md` (v8 → v9) has a banner pointing to this guide. ## How it was checked - Every identifier in the guide was checked against the SDK source, `stream-chat-js` `src/` and `@stream-io/i18n` / `state-store`. All 1,292 root exports were listed with the TS compiler, and every recommended hook is a root export. - About 40 v10 snippets typecheck against `package/src`. - The detection, breaks-table and leftover greps were run on the v9 and v10 SampleApps. ## Needs a decision - **Deep link vs reopen-at-latest.** If an app starts `jumpToMessage` in a screen-level `useLayoutEffect`, the SDK's jump to the latest messages may fire first. The SDK tests only cover a jump started before `<Channel>` mounts, so the guide recommends that order. Worth a test or a guard in the hook. - Phase 1 asks which pre-release to use when no stable 10.x exists. Check that this fits the prebuilt prompt during the RC period. ## Notes - The raw link to the stream-chat-js guide resolves once its PR is merged into `release-v10`. - The local `package/node_modules/stream-chat` is rc.26; `yarn install` brings it to rc.30. ## Related PRs The three guides link to each other; review together: - stream-chat-js: GetStream/stream-chat-js#1984 (merge first: the React and RN guides link to its raw URL) - stream-chat-react: GetStream/stream-chat-react#3377 - stream-chat-react-native: #3918
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.
Tickets:
🎯 Goal
Fixes for the must-have V10 issues from the board triage. Each commit fixes one ticket.
a0354684cb5705f953setupCommandUIMiddlewaresno longer inserts duplicate middlewareb0d28db847a0376993🛠 Implementation details
REACT-1486 - optimistic edit of a translated message
Commit:
a0354684cThe fix is in stream-chat-js (GetStream/stream-chat-js#1975). This commit adds the RN regression test, which edits an auto-translated message through the composer and checks the rendered row while the request is in flight. It fails until
stream-chatis bumped to an rc that includes GetStream/stream-chat-js#1975.REACT-1489 - duplicate command middleware
Commit:
b5705f953setupCommandUIMiddlewaresinserts four middleware but passedunique: trueonly on the first. The composer setup function runs again whenever the composer subscribes, which happens every time a channel opens, and on everyclient.configchange. The draft command injection, the active command guard and the command string extraction piled up as a result. Each copy of the draft injection prepends the command, so a draft saved with an active command came out as/giphy /giphy cats.All four inserts now pass
unique: true, so running the setup again replaces them.REACT-1490 - channel list stuck on channels an event added
Commit:
b0d28db84ChannelManager.ingestChannel()puts a channel into every matching paginator, including one that was never queried.usePaginatedChannelstreated a list as unloaded only whilechannels === undefined, andloadNextPagerefuses a paginator that was never queried. A list that mounted after an event reached its paginator showed only those channels until pull-to-refresh. That happens when the app opens a channel from a push notification and the user goes back to the list, or with a second list, such as archived channels, that mounts later.A paginator that was never queried now counts as unloaded too, so the list runs its first query. The offline DB seed and a failed first query both mark the paginator as queried, so neither causes an extra query.
REACT-1487 - reopening a channel or thread on an older page
Commit:
7a0376993The paginators of a channel and a thread outlive the screen. After a jump to a quoted, pinned or searched message, reopening the channel or thread showed that older page.
<Channel>relied onwatch()to go back to the newest messages, butwatch()returns early for a channel that is already watched and loaded since GetStream/stream-chat-js#1943. v9 re-watched on open and landed on the newest messages.The new public
useJumpToLatestOnOpen()hook callsjumpToTheLatestMessage()when a channel or thread opens on an older page. The newest page is normally still loaded, so this switches back locally without a request. It does nothing when a jump already landed or is in flight, so a deep link from the screen still lands on its target. It also does nothing when<Channel>is about to jump to the first unread message, or withinitializeOnMount={false}. It runs in a layout effect so the old page isn't painted first, and its dependencies are stable, so it runs once per open.ChannelShellruns the hook from an emptyJumpToLatestOnOpencomponent under its providers, the same way it rendersNotificationAnnouncer. That covers<Channel>,<Thread>and any message list, including custom ones.ChannelShelltakesinitializeOnMountas an internal prop that<Channel>passes on. The hook is exported for apps that setinitializeOnMount={false}and still want this behaviour.The
MessageList in a threadtest setup now seeds replies withsetItems(), the way a thread seedslatest_replies. It used to writeitemsstraight into the paginator state, which leaves no intervals and looked like a list that isn't showing its newest page.🎨 UI Changes
None.
🧪 Testing
setupCommandUIMiddlewaresthree times on one composer leaves one of each middleware. Without the fix there are three.ChannelListwhose paginator got a channel fromingestChannel()before it was queried runs its first query on mount and shows the queried page. Without the fix it never queries.Channeltests cover reopening on an older page, a deep link that already landed, a jump in flight,initializeOnMount={false}and the first unread jump.Threadtests cover the first three. Without the fix, only the two reopening tests fail.yarn test:typecheck,eslint,prettierandyarn buildpass, apart from the REACT-1486 test above.☑️ Checklist
developbranch