fix: preserve committed pages in connector range management in combo-box#9220
fix: preserve committed pages in connector range management in combo-box#9220DiegoCardoso wants to merge 6 commits intomainfrom
Conversation
`commitPage` previously did not delete the entry from `pageCallbacks`, so subsequent `dataProvider` requests for different pages saw stale active-range entries — the non-sequential branch then wiped already- committed data and the data-fetch flow stalled when a far-page request came in (e.g. a programmatic `scrollToIndex` jump on lazy data). Track committed pages in a dedicated set so the active-range eviction trigger stays accurate while pageCallbacks reflects only pending requests. Also relax the non-sequential branch to fetch only the new page rather than wiping everything: the original wipe-and-refetch was a side effect of the stale-pageCallbacks bug, and removing it lets the connector serve far-page requests correctly without triggering a stuck-loading cycle. Adjusts ItemCountUnknownComboBoxIT and ComboBoxClientSideDataRangeIT to match the new fetch cadence (fewer redundant fetches now that committed data isn't needlessly evicted on non-sequential scroll). The behavior under test is preserved; the implementation-detail RangeLog assertions and over-aggressive eviction expectations are relaxed, with comments pointing to the connector fix. Marks LazyLoadingIT.setComponentRenderer_scrollDown_scrollUp_itemsRendered as @ignore — pre-existing FlowComponentRenderer behavior that relied on the connector's wipe-and-refetch to re-attach component-renderer slots after scroll. Tracked separately as a follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s on non-contiguous request Two follow-on fixes to the connector range-management change: 1. Cover all pending pages in the non-sequential setViewportRange. `_scroller.scrollIntoView(N)` triggers per-page `dataProvider` calls for every visible placeholder page in one rAF batch. Each call hit the non-sequential branch and fired its own `setViewportRange` RPC. These RPCs overwrite each other on the server (last write wins), so any earlier-pending page that wasn't covered by the latest range never received data — its `pageCallbacks` entry lingered and the combo-box stayed `loading=true`. The fix expands the range to cover every entry in `pageCallbacks` so the latest RPC always covers the earlier ones. 2. Evict ComponentRenderer-rendered committed pages outside the new range so their stale node ids don't get re-bound on scroll-back. PR #9220 preserves committed pages by design, but server-side ComponentRenderer components are passivated when items leave the KeyMapper's active set — virtual children are detached and the `*_nodeid` properties cached on the client point at deleted state- tree nodes. Re-rendering from the cached items showed stale (or empty) renderer slots. The eviction is scoped to pages whose first item carries an `*_nodeid` property, so plain-data pages stay intact and `ComboBoxClientSideDataRangeIT`'s page-0-preserved assertion still holds. Un-`@Ignore`s `LazyLoadingIT.setComponentRenderer_scrollDown_scrollUp_itemsRendered`. The pre-existing `@Ignore` blamed FlowComponentRenderer; the actual cause was the combination above. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Flatten the filter callback to a direct boolean expression instead of an inline early-return guard. - Drop the redundant length check: clearPageCallbacks runs forEach over its input, which is a no-op on an empty array. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop comments that explain what the code USED to do (or describe the PR rather than the resulting code). Keep only comments that document non-obvious WHY of the resulting code — invariants, server-behavior contracts, hidden constraints. Historical context moved to PR #9220. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Reviewer notes — context for the trimmed comments The latest commit (
|
Adds a `non-contiguous page requests` describe block to the connector WTR suite covering the three connector behaviors changed in this PR: 1. A multi-page rAF batch fires one setViewportRange covering every pending page, not per-page (regression guard for the stuck-loading bug — `setViewportRange` is last-write-wins on the server). 2. Already-committed pages no longer drag their entries into a later non-contiguous request range. 3. ComponentRenderer-rendered committed pages are evicted on a non-contiguous jump while plain-data pages stay cached. Also moves the `confirmUpdate` server stub and `plainItems` / `rendererItems` factories into `shared.ts` so additional test cases can use them. Run via `node scripts/wtr.js combo-box`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|



Summary
A lazy combo-box can get stuck on
loading=truewhen the connector receives a programmaticscrollToIndexjump to an unloaded far page — the existing range-management logic wipes already-committed data and the data-fetch flow stalls. This fix tracks committed pages separately from pending callbacks so the active-range eviction trigger stays accurate, and the non-sequential branch fires a viewport-range RPC that covers all pending pages (the server's last-write-wins semantics mean a per-page RPC drops earlier-pending requests).ComponentRenderer-rendered pages outside the new viewport are evicted client-side: the server passivates the rendered components when items leave the KeyMapper's active set, so cached node ids would otherwise bind to detached virtual children. Plain-data pages stay in cache.
This is a prerequisite for the
focusSelectedItemfeature in #9194, which exercises this path on every open with a far-positioned selected item.Notes for reviewers
A summary comment with the deeper context behind the assertion changes in
ComboBoxClientSideDataRangeIT,ItemCountUnknownComboBoxIT, and thecommitPage/ non-sequential-branch fixes is posted as a separate PR comment to keep the diff readable.