Skip to content

Commit dae50b8

Browse files
fixing bug where re-setting of a state would cause incosistencies
1 parent eeb869e commit dae50b8

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

src/States.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ export class States <State extends string> implements Iterable<[id: string, stat
22
readonly byState: Partial<{ [state in State]: Set<string> }> = {}
33

44
set (id: string, state: State): void {
5-
this.clear(id, state)
5+
if (!this.clear(id, state)) {
6+
return
7+
}
68
const bucket = this.byState[state]
79
if (bucket === undefined) {
810
this.byState[state] = new Set([id])
@@ -26,19 +28,20 @@ export class States <State extends string> implements Iterable<[id: string, stat
2628
}
2729
}
2830

29-
private clear (id: string, unlessState?: State): void {
31+
private clear (id: string, unlessState?: State): boolean {
3032
for (const bucketState in this.byState) {
31-
if (bucketState === unlessState) return
32-
const bucket = this.byState[bucketState]
33-
if (bucket !== undefined) {
34-
bucket.delete(id)
35-
if (bucket.size === 0) {
36-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
37-
delete this.byState[bucketState]
38-
}
39-
return
33+
const bucket = this.byState[bucketState] as Set<string>
34+
if (bucketState === unlessState && bucket.has(id)) {
35+
return false
36+
}
37+
bucket.delete(id)
38+
if (bucket.size === 0) {
39+
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
40+
delete this.byState[bucketState]
4041
}
42+
return true
4143
}
44+
return true
4245
}
4346

4447
has (id: string): boolean {

test/States.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,21 @@ test('has state', t => {
8080
t.notOk(states.has('a'))
8181
t.end()
8282
})
83+
84+
test('setting an existing value again should quick exit', t => {
85+
const states = new States()
86+
states.set('a', '1')
87+
states.set('a', '1')
88+
t.equals(states.get('a'), '1')
89+
t.end()
90+
})
91+
92+
test('setting an existing key again should not keep copies', t => {
93+
const states = new States()
94+
states.set('b', '2')
95+
states.set('a', '1')
96+
states.set('a', '2')
97+
states.set('a', '3')
98+
t.deepEquals(Array.from(states), [['b', '2'], ['a', '3']])
99+
t.end()
100+
})

0 commit comments

Comments
 (0)