Skip to content

Commit fbd6a66

Browse files
committed
fix(Entity): Return a referentially equal state if state did not change
1 parent 335d255 commit fbd6a66

File tree

5 files changed

+73
-37
lines changed

5 files changed

+73
-37
lines changed

modules/entity/spec/sorted_state_adapter.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ describe('Sorted State Adapter', () => {
3636

3737
const readded = adapter.addOne(TheGreatGatsby, withOneEntity);
3838

39-
expect(readded).toEqual(withOneEntity);
39+
expect(readded).toBe(withOneEntity);
4040
});
4141

4242
it('should let you add many entities to the state', () => {
@@ -150,7 +150,7 @@ describe('Sorted State Adapter', () => {
150150
state
151151
);
152152

153-
expect(withUpdates).toEqual(state);
153+
expect(withUpdates).toBe(state);
154154
});
155155

156156
it('should let you update the id of entity', () => {

modules/entity/spec/unsorted_state_adapter.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('Unsorted State Adapter', () => {
3535

3636
const readded = adapter.addOne(TheGreatGatsby, withOneEntity);
3737

38-
expect(readded).toEqual(withOneEntity);
38+
expect(readded).toBe(withOneEntity);
3939
});
4040

4141
it('should let you add many entities to the state', () => {
@@ -149,7 +149,7 @@ describe('Unsorted State Adapter', () => {
149149
state
150150
);
151151

152-
expect(withUpdates).toEqual(state);
152+
expect(withUpdates).toBe(state);
153153
});
154154

155155
it('should let you update the id of entity', () => {

modules/entity/src/sorted_state_adapter.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,31 @@ export function createSortedStateAdapter<T>(
1919
selectId
2020
);
2121

22-
function addOneMutably(entity: T, state: R): void {
22+
function addOneMutably(entity: T, state: R): boolean {
2323
const key = selectId(entity);
24-
const index = state.ids.indexOf(key);
2524

26-
if (index !== -1) {
27-
return;
25+
if (key in state.entities) {
26+
return false;
2827
}
2928

3029
const insertAt = findTargetIndex(state, entity);
3130
state.ids.splice(insertAt, 0, key);
3231
state.entities[key] = entity;
32+
33+
return true;
3334
}
3435

35-
function addManyMutably(newModels: T[], state: R): void {
36+
function addManyMutably(newModels: T[], state: R): boolean {
37+
let didMutate = false;
38+
3639
for (let index in newModels) {
37-
addOneMutably(newModels[index], state);
40+
didMutate = addOneMutably(newModels[index], state) || didMutate;
3841
}
42+
43+
return didMutate;
3944
}
4045

41-
function addAllMutably(models: T[], state: R): void {
46+
function addAllMutably(models: T[], state: R): boolean {
4247
const sortedModels = models.sort(sort);
4348

4449
state.entities = {};
@@ -47,13 +52,13 @@ export function createSortedStateAdapter<T>(
4752
state.entities[id] = model;
4853
return id;
4954
});
50-
}
5155

52-
function updateOneMutably(update: Update<T>, state: R): void {
53-
const index = state.ids.indexOf(update.id);
56+
return true;
57+
}
5458

55-
if (index === -1) {
56-
return;
59+
function updateOneMutably(update: Update<T>, state: R): boolean {
60+
if (!(update.id in state.entities)) {
61+
return false;
5762
}
5863

5964
const original = state.entities[update.id];
@@ -64,14 +69,16 @@ export function createSortedStateAdapter<T>(
6469
if (result === 0) {
6570
if (updatedKey !== update.id) {
6671
delete state.entities[update.id];
72+
const index = state.ids.indexOf(update.id);
6773
state.ids[index] = updatedKey;
6874
}
6975

7076
state.entities[updatedKey] = updated;
7177

72-
return;
78+
return true;
7379
}
7480

81+
const index = state.ids.indexOf(update.id);
7582
state.ids.splice(index, 1);
7683
state.ids.splice(findTargetIndex(state, updated), 0, updatedKey);
7784

@@ -80,12 +87,18 @@ export function createSortedStateAdapter<T>(
8087
}
8188

8289
state.entities[updatedKey] = updated;
90+
91+
return true;
8392
}
8493

85-
function updateManyMutably(updates: Update<T>[], state: R): void {
94+
function updateManyMutably(updates: Update<T>[], state: R): boolean {
95+
let didMutate = false;
96+
8697
for (let index in updates) {
87-
updateOneMutably(updates[index], state);
98+
didMutate = updateOneMutably(updates[index], state) || didMutate;
8899
}
100+
101+
return didMutate;
89102
}
90103

91104
function findTargetIndex(state: R, model: T) {
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import { EntityState, EntityStateAdapter } from './models';
22

33
export function createStateOperator<V, R>(
4-
mutator: (arg: R, state: EntityState<V>) => void
4+
mutator: (arg: R, state: EntityState<V>) => boolean
55
) {
66
return function operation<S extends EntityState<V>>(arg: R, state: S): S {
77
const clonedEntityState: EntityState<V> = {
88
ids: [...state.ids],
99
entities: { ...state.entities },
1010
};
1111

12-
mutator(arg, clonedEntityState);
12+
const didMutate = mutator(arg, clonedEntityState);
1313

14-
return Object.assign({}, state, clonedEntityState);
14+
if (didMutate) {
15+
return Object.assign({}, state, clonedEntityState);
16+
}
17+
18+
return state;
1519
};
1620
}

modules/entity/src/unsorted_state_adapter.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,59 @@ export function createUnsortedStateAdapter<T>(
66
): EntityStateAdapter<T> {
77
type R = EntityState<T>;
88

9-
function addOneMutably(entity: T, state: R): void {
9+
function addOneMutably(entity: T, state: R): boolean {
1010
const key = selectId(entity);
11-
const index = state.ids.indexOf(key);
1211

13-
if (index !== -1) {
14-
return;
12+
if (key in state.entities) {
13+
return false;
1514
}
1615

1716
state.ids.push(key);
1817
state.entities[key] = entity;
18+
19+
return true;
1920
}
2021

21-
function addManyMutably(entities: T[], state: R): void {
22+
function addManyMutably(entities: T[], state: R): boolean {
23+
let didMutate = false;
24+
2225
for (let index in entities) {
23-
addOneMutably(entities[index], state);
26+
didMutate = addOneMutably(entities[index], state) || didMutate;
2427
}
28+
29+
return didMutate;
2530
}
2631

27-
function addAllMutably(entities: T[], state: R): void {
32+
function addAllMutably(entities: T[], state: R): boolean {
2833
state.ids = [];
2934
state.entities = {};
3035

3136
addManyMutably(entities, state);
37+
38+
return true;
3239
}
3340

34-
function removeOneMutably(key: string, state: R): void {
41+
function removeOneMutably(key: string, state: R): boolean {
3542
const index = state.ids.indexOf(key);
3643

3744
if (index === -1) {
38-
return;
45+
return false;
3946
}
4047

4148
state.ids.splice(index, 1);
4249
delete state.entities[key];
50+
51+
return true;
4352
}
4453

45-
function removeManyMutably(keys: string[], state: R): void {
54+
function removeManyMutably(keys: string[], state: R): boolean {
55+
let didMutate = false;
56+
4657
for (let index in keys) {
47-
removeOneMutably(keys[index], state);
58+
didMutate = removeOneMutably(keys[index], state) || didMutate;
4859
}
60+
61+
return didMutate;
4962
}
5063

5164
function removeAll<S extends R>(state: S): S {
@@ -55,11 +68,11 @@ export function createUnsortedStateAdapter<T>(
5568
});
5669
}
5770

58-
function updateOneMutably(update: Update<T>, state: R): void {
71+
function updateOneMutably(update: Update<T>, state: R): boolean {
5972
const index = state.ids.indexOf(update.id);
6073

6174
if (index === -1) {
62-
return;
75+
return false;
6376
}
6477

6578
const original = state.entities[update.id];
@@ -72,12 +85,18 @@ export function createUnsortedStateAdapter<T>(
7285
}
7386

7487
state.entities[newKey] = updated;
88+
89+
return true;
7590
}
7691

77-
function updateManyMutably(updates: Update<T>[], state: R): void {
92+
function updateManyMutably(updates: Update<T>[], state: R): boolean {
93+
let didMutate = false;
94+
7895
for (let index in updates) {
79-
updateOneMutably(updates[index], state);
96+
didMutate = updateOneMutably(updates[index], state) || didMutate;
8097
}
98+
99+
return didMutate;
81100
}
82101

83102
return {

0 commit comments

Comments
 (0)