feat: migrate ChannelPaginatorsOrchestrator to ChannelManager - #1813
Open
MartinCupela wants to merge 9 commits into
Open
feat: migrate ChannelPaginatorsOrchestrator to ChannelManager#1813MartinCupela wants to merge 9 commits into
MartinCupela wants to merge 9 commits into
Conversation
… event cid fallback
… and delete the legacy manager
MartinCupela
requested review from
arnautov-anton,
isekovanic,
oliverlaz,
santhoshvai,
szuperaz and
vishalnarkhede
as code owners
August 5, 2026 13:13
…manager # Conflicts: # src/client.ts
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
ChannelPaginatorsOrchestratorbecomesChannelManager, and the legacysrc/channel_manager.tsisdeleted. One manager now holds N channel lists — each a
ChannelPaginator— keeps them in sync through anEventHandlerPipelineper event type, and arbitrates ownership when a channel matches several lists.The rename is the easy half. The bulk of this PR is feature parity: the legacy manager still had
behavior the paginator stack did not, so those gaps were closed first and the deletion comes last.
What was ported
query()requestswithResponse: trueand keepspredefined_filterverbatim; it drives local matching (buildMatchFilters) and ordering (effectiveSort)message.newfor an archived channel was ingested into a list the server filters to{ archived: false }hidden;channel.hiddenre-evaluates filters{ hidden: true }list — this keeps themretryCountis a paginator option andChannelPaginatordefaults toDEFAULT_QUERY_CHANNELS_RETRY_COUNTgetCidFromEventhelper for the cached lookup and the fetchupdateListsthrew on events whose only identity isevent.channel.cid;removeItemignored themDeliberately not ported, each with a reason in
decisions.md:state.initialized,pagination.isLoadingNext,abortInFlightQuery, the 10 named handler overrides,allowNotLoadedChannelPromotionForEvent,members-based channel construction, and thepromoteChannelpinned-ordering rules.
Bugs found while porting
Each of these was pre-existing and is covered by a test that fails without the fix:
sortsetter dropped the comparator's resolvers — after anypaginator.sort = …,last_message_atresolved to
channel.data.last_message_at(undefined) instead of the message paginator's value, andequal sort values ordered non-deterministically. Comparator construction now goes through one
buildSortComparator().retryCountwas off by one —3meant 3 attempts / 2 waits; it now means 3 retries / 4 attempts,matching what the legacy manager's own tests asserted.
removeItemhandler read onlyevent.cid— achannel.deletedwhose cid arrives nested inevent.channelwas ignored, so the channel stayed in every list.describe.each(['channel.deleted', 'channel.hidden'])never ran the hidden case — all three casesdispatched a hardcoded
channel.deleted, which is why the missing handler went unnoticed.client.test.jstests — the fixture built ten "channels" sharing one cid withsame-millisecond timestamps, so ordering hinged on random uuids (~5% failure rate).
Breaking changes
ChannelManagerkeeps its name but is a different class — code importing it still compiles, which isthe risky part. Full tables (state, methods, options, types, helpers) are in the new
## ChannelManagersection of
v9-to-v10-migration-guide-methods.md, including aworked replacement for
promoteChanneland a v10-RC → final rename table. In short:state.channels/pagination/initialized/error→state.paginators, with list state onpaginator.state(items,hasMoreTail,isLoading,lastQueryError).queryChannels()/loadNext()/setChannels()/setQueryChannelsRequest()/setOptions()/setEventHandlerOverrides()→ paginator methods and the pipeline API.lockChannelOrder→paginatorOptions.lockItemOrder;abortInFlightQueryandallowNotLoadedChannelPromotionForEventremoved (the latter replaced by inserting the exportedignoreEventsForUnknownChannelsatindex: 0).buildFilters()is gone stack-wide →buildQueryFilters()(request + offline cache key) andbuildMatchFilters()(local matching).ChannelQueryShapeis now thequeryChannelsrequest itself.promoteChannel& friends).retryCountsemantics, offline cache re-keyed,sortComparatorassignment no longer survives a sort change (usesortComparatorFactory),channel.updated/channel.truncatedre-emit instead of no-op.