Skip to content

Commit fdc845d

Browse files
committed
1 parent 3b8d7a9 commit fdc845d

File tree

3 files changed

+60
-51
lines changed

3 files changed

+60
-51
lines changed

packages/toolkit/src/entities/sorted_state_adapter.ts

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -71,32 +71,40 @@ export function createSortedStateAdapter<T>(
7171
return updateManyMutably([update], state)
7272
}
7373

74-
// eslint-disable-next-line @typescript-eslint/prefer-readonly-parameter-types
75-
function takeUpdatedModel(models: T[], update: Update<T>, state: R): boolean {
76-
if (!(update.id in state.entities)) {
77-
return false
78-
}
79-
80-
const original = state.entities[update.id]
81-
const updated = Object.assign({}, original, update.changes)
82-
const newKey = selectIdValue(updated, selectId)
83-
84-
delete state.entities[update.id]
85-
86-
models.push(updated)
87-
88-
return newKey !== update.id
89-
}
90-
9174
function updateManyMutably(
9275
updates: ReadonlyArray<Update<T>>,
9376
state: R
9477
): void {
95-
const models: T[] = []
78+
const changedKeys: EntityId[] = []
79+
80+
const updatesPerEntity: { [id: string]: Update<T> } = {}
81+
82+
updates.forEach((update) => {
83+
if (update.id in state.entities) {
84+
updatesPerEntity[update.id] = {
85+
id: update.id,
86+
changes: {
87+
...(updatesPerEntity[update.id]
88+
? updatesPerEntity[update.id].changes
89+
: null),
90+
...update.changes,
91+
},
92+
}
93+
}
94+
const newId = selectId(update.changes as T)
95+
if (newId !== undefined && update.id !== newId) {
96+
changedKeys.push(update.id)
97+
}
98+
})
9699

97-
updates.forEach((update) => takeUpdatedModel(models, update, state))
100+
updates = Object.values(updatesPerEntity)
98101

99-
if (models.length !== 0) {
102+
if (updates.length > 0) {
103+
const models = updates.map(
104+
(update) =>
105+
Object.assign({}, state.entities[update.id], update.changes) as T
106+
)
107+
changedKeys.forEach((key) => delete state.entities[key])
100108
merge(models, state)
101109
}
102110
}

packages/toolkit/src/entities/tests/sorted_state_adapter.test.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ describe('Sorted State Adapter', () => {
3030
beforeEach(() => {
3131
adapter = createEntityAdapter({
3232
selectId: (book: BookModel) => book.id,
33-
sortComparer: (a, b) => {
34-
return a.title.localeCompare(b.title)
35-
},
33+
sortComparer: (a, b) => a.title.localeCompare(b.title),
3634
})
3735

3836
state = { ids: [], entities: {} }
@@ -652,12 +650,20 @@ describe('Sorted State Adapter', () => {
652650
test('updateMany', () => {
653651
const firstChange = { title: 'First Change' }
654652
const secondChange = { title: 'Second Change' }
655-
const withMany = adapter.setAll(state, [TheGreatGatsby, AClockworkOrange])
653+
const thirdChange = { title: 'Third Change' }
654+
const fourthChange = { author: 'Fourth Change' }
655+
const withMany = adapter.setAll(state, [
656+
TheGreatGatsby,
657+
AClockworkOrange,
658+
TheHobbit,
659+
])
656660

657661
const result = createNextState(withMany, (draft) => {
658662
adapter.updateMany(draft, [
659-
{ id: TheGreatGatsby.id, changes: firstChange },
660-
{ id: AClockworkOrange.id, changes: secondChange },
663+
{ id: TheHobbit.id, changes: firstChange },
664+
{ id: TheGreatGatsby.id, changes: secondChange },
665+
{ id: AClockworkOrange.id, changes: thirdChange },
666+
{ id: TheHobbit.id, changes: fourthChange },
661667
])
662668
})
663669

@@ -666,14 +672,20 @@ describe('Sorted State Adapter', () => {
666672
"entities": Object {
667673
"aco": Object {
668674
"id": "aco",
669-
"title": "Second Change",
675+
"title": "Third Change",
670676
},
671677
"tgg": Object {
672678
"id": "tgg",
679+
"title": "Second Change",
680+
},
681+
"th": Object {
682+
"author": "Fourth Change",
683+
"id": "th",
673684
"title": "First Change",
674685
},
675686
},
676687
"ids": Array [
688+
"th",
677689
"tgg",
678690
"aco",
679691
],

packages/toolkit/src/entities/unsorted_state_adapter.ts

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,6 @@ export function createUnsortedStateAdapter<T>(
9898
})
9999
}
100100

101-
function takeNewKey(
102-
keys: { [id: string]: EntityId },
103-
update: Update<T>,
104-
state: R
105-
): boolean {
106-
const original = state.entities[update.id]
107-
const updated: T = Object.assign({}, original, update.changes)
108-
const newKey = selectIdValue(updated, selectId)
109-
const hasNewKey = newKey !== update.id
110-
111-
if (hasNewKey) {
112-
keys[update.id] = newKey
113-
delete state.entities[update.id]
114-
}
115-
116-
state.entities[newKey] = updated
117-
118-
return hasNewKey
119-
}
120-
121101
function updateOneMutably(update: Update<T>, state: R): void {
122102
return updateManyMutably([update], state)
123103
}
@@ -127,7 +107,6 @@ export function createUnsortedStateAdapter<T>(
127107
state: R
128108
): void {
129109
const newKeys: { [id: string]: EntityId } = {}
130-
131110
const updatesPerEntity: { [id: string]: Update<T> } = {}
132111

133112
updates.forEach((update) => {
@@ -146,16 +125,26 @@ export function createUnsortedStateAdapter<T>(
146125
},
147126
}
148127
}
128+
const newId = selectId(update.changes as T)
129+
if (newId !== undefined && update.id !== newId) {
130+
newKeys[update.id] = newId;
131+
}
149132
})
150133

151134
updates = Object.values(updatesPerEntity)
152135

153136
const didMutateEntities = updates.length > 0
154137

155138
if (didMutateEntities) {
156-
const didMutateIds =
157-
updates.filter((update) => takeNewKey(newKeys, update, state)).length >
158-
0
139+
const changedKeys = Object.keys(newKeys);
140+
const didMutateIds = changedKeys.length > 0;
141+
142+
updates.forEach((update) => {
143+
const newEntity = Object.assign({}, state.entities[update.id], update.changes)
144+
state.entities[newKeys[update.id] || update.id] = newEntity
145+
})
146+
147+
changedKeys.forEach(key => delete state.entities[key])
159148

160149
if (didMutateIds) {
161150
state.ids = state.ids.map((id) => newKeys[id] || id)

0 commit comments

Comments
 (0)