Skip to content

Commit c6be881

Browse files
committed
Sort when items are removed
1 parent 6dac1d2 commit c6be881

File tree

2 files changed

+107
-5
lines changed

2 files changed

+107
-5
lines changed

src/entities/sorted_state_adapter.test.ts

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { EntityStateAdapter, EntityState } from './models'
1+
import { EntityStateAdapter, EntityState, EntityAdapter } from './models'
22
import { createEntityAdapter } from './create_adapter'
33
import { createAction } from '../createAction'
44
import {
@@ -753,4 +753,75 @@ describe('Sorted State Adapter', () => {
753753
`)
754754
})
755755
})
756+
757+
describe('Sorted adapter indices', () => {
758+
const booksAdapter = createEntityAdapter<BookModel>({
759+
selectId: (book: BookModel) => book.id,
760+
sortComparer: (a, b) => {
761+
return a.title.localeCompare(b.title)
762+
},
763+
indices: {
764+
byId: (a, b) => a.id.localeCompare(b.id),
765+
byTitleLength: (a, b) => a.title.length - b.title.length
766+
}
767+
})
768+
769+
const initialState = booksAdapter.getInitialState()
770+
beforeEach(() => {})
771+
772+
it('Does some initial sorting', () => {
773+
const loadedState = booksAdapter.setAll(initialState, [
774+
TheGreatGatsby,
775+
AClockworkOrange,
776+
AnimalFarm
777+
])
778+
expect(loadedState.indices.byId.length).toBe(3)
779+
})
780+
781+
it('Resorts only updated indices', () => {
782+
const loadedState = booksAdapter.setAll(initialState, [
783+
TheGreatGatsby,
784+
AClockworkOrange,
785+
AnimalFarm
786+
])
787+
788+
const updatedState = booksAdapter.updateOne(loadedState, {
789+
id: AnimalFarm.id,
790+
changes: {
791+
title: 'This is a really long title, very long indeed'
792+
}
793+
})
794+
795+
expect(updatedState.indices.byTitleLength[2]).toBe(AnimalFarm.id)
796+
expect(updatedState.indices.byId).toBe(loadedState.indices.byId)
797+
})
798+
799+
it('Updates indices when items are removed', () => {
800+
const loadedState = booksAdapter.setAll(initialState, [
801+
TheGreatGatsby,
802+
AClockworkOrange,
803+
AnimalFarm
804+
])
805+
806+
const updatedState1 = booksAdapter.removeOne(
807+
loadedState,
808+
AClockworkOrange.id
809+
)
810+
811+
expect(updatedState1.indices.byId.length).toBe(2)
812+
expect(updatedState1.indices.byTitleLength.length).toBe(2)
813+
814+
const updatedState2 = booksAdapter.removeMany(loadedState, [
815+
AClockworkOrange.id
816+
])
817+
818+
expect(updatedState2.indices.byId.length).toBe(2)
819+
expect(updatedState2.indices.byTitleLength.length).toBe(2)
820+
821+
const updatedState3 = booksAdapter.removeAll(loadedState)
822+
823+
expect(updatedState3.indices.byId.length).toBe(0)
824+
expect(updatedState3.indices.byTitleLength.length).toBe(0)
825+
})
826+
})
756827
})

src/entities/sorted_state_adapter.ts

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {
77
EntityId,
88
IndexComparers
99
} from './models'
10-
import { createStateOperator } from './state_adapter'
10+
import {
11+
createStateOperator,
12+
createSingleArgumentStateOperator
13+
} from './state_adapter'
1114
import { createUnsortedStateAdapter } from './unsorted_state_adapter'
1215
import {
1316
selectIdValue,
@@ -141,6 +144,34 @@ export function createSortedStateAdapter<T>(
141144
state.entities[selectId(model)] = model
142145
})
143146

147+
updateSortedIndices(state)
148+
}
149+
150+
function removeOneSortedIndices(key: EntityId, state: R): void {
151+
removeOne(state, key)
152+
updateSortedIndices(state)
153+
}
154+
155+
function removeManySortedIndices(keys: EntityId[], state: R): void {
156+
removeMany(state, keys)
157+
updateSortedIndices(state)
158+
}
159+
160+
function removeAllSortedIndices(state: R): void {
161+
const newIndices = {} as any
162+
163+
for (let key in indices) {
164+
newIndices[key] = []
165+
}
166+
167+
Object.assign(state, {
168+
ids: [],
169+
entities: {},
170+
indices: newIndices
171+
})
172+
}
173+
174+
function updateSortedIndices(state: EntityState<T>) {
144175
const allEntities = Object.values(state.entities) as T[]
145176
updateSortedIds(
146177
(state as unknown) as Record<string, EntityId[]>,
@@ -155,9 +186,9 @@ export function createSortedStateAdapter<T>(
155186
}
156187

157188
return {
158-
removeOne,
159-
removeMany,
160-
removeAll,
189+
removeOne: createStateOperator(removeOneSortedIndices),
190+
removeMany: createStateOperator(removeManySortedIndices),
191+
removeAll: createSingleArgumentStateOperator(removeAllSortedIndices),
161192
addOne: createStateOperator(addOneMutably),
162193
updateOne: createStateOperator(updateOneMutably),
163194
upsertOne: createStateOperator(upsertOneMutably),

0 commit comments

Comments
 (0)