perf(web): свод 2 — begin(load) не очищает данные до первого ответа

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-28 22:22:43 +04:00
parent 78e06583f4
commit 325c1c5f15
2 changed files with 25 additions and 1 deletions

View File

@ -125,6 +125,8 @@ export function createSheetPagingState() {
};
}
// Инвариант для хука: settled надо слать для КАЖДОГО поколения; settled старого поколения игнорируется,
// поэтому loading, выставленный begin(load), снимает только settled текущего поколения.
export function svod2PagingReducer(state, action) {
if (action.generation !== state.generation && action.type !== 'begin') return state;
switch (action.type) {
@ -135,7 +137,6 @@ export function svod2PagingReducer(state, action) {
pendingQueryKey: action.queryKey,
error: '',
loading: action.mode === 'load' ? true : state.loading,
...(action.mode === 'load' ? { pages: new Map(), total: 0, facets: null } : {}),
};
case 'page': {
const first = state.dataGeneration !== action.generation;

View File

@ -256,3 +256,26 @@ test('facets и settled текущего поколения', () => {
s = svod2PagingReducer(s, { type: 'settled', generation: 1 });
assert.equal(s.loading, false);
});
test('begin(load) оставляет прежние pages/total/facets до первого ответа нового поколения', () => {
let s = begin(createSheetPagingState(), 1, 'load');
s = page(s, 1, 0, ['a'], 5);
s = svod2PagingReducer(s, { type: 'facets', generation: 1, facets: { total: 5 } });
s = begin(s, 2, 'load', 'k2');
assert.equal(s.loading, true);
assert.deepEqual(s.pages.get(0), ['a']);
assert.equal(s.total, 5);
assert.deepEqual(s.facets, { total: 5 });
s = page(s, 2, 0, ['z'], 1);
assert.deepEqual([...s.pages.keys()], [0]);
assert.deepEqual(s.pages.get(0), ['z']);
});
test('refine поверх load: loading снимает settled нового поколения, старого - игнорируется', () => {
let s = begin(createSheetPagingState(), 1, 'load');
s = begin(s, 2, 'refine');
assert.equal(s.loading, true);
assert.equal(svod2PagingReducer(s, { type: 'settled', generation: 1 }), s);
s = svod2PagingReducer(s, { type: 'settled', generation: 2 });
assert.equal(s.loading, false);
});