Skip to content

Commit 825c67f

Browse files
Merge pull request cerebral#115 from cerebral/derivedFix
fix(overmind): make sure derived also updates on object changes
2 parents c85dc03 + 6b927c6 commit 825c67f

File tree

4 files changed

+33
-13
lines changed

4 files changed

+33
-13
lines changed

packages/node_modules/overmind/src/derived.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,20 @@ export default class Derived {
2323
this.paths = proxyStateTree.clearPathsTracking(trackId)
2424
if (!this.proxyStateTreeListener) {
2525
this.proxyStateTreeListener = proxyStateTree.addMutationListener(
26-
(mutation, flushId) => {
27-
if (this.paths.has(mutation.path)) {
28-
eventHub.emitAsync(EventType.DERIVED_DIRTY, {
29-
path,
30-
flushId,
31-
})
32-
this.isDirty = true
26+
(_, paths, flushId) => {
27+
if (this.isDirty) {
28+
return
29+
}
30+
31+
for (let path of paths) {
32+
if (this.paths.has(path)) {
33+
eventHub.emitAsync(EventType.DERIVED_DIRTY, {
34+
path,
35+
flushId,
36+
})
37+
this.isDirty = true
38+
return
39+
}
3340
}
3441
}
3542
)

packages/node_modules/proxy-state-tree/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,15 @@ const tree = new ProxyStateTree({
165165
})
166166
const state = tree.get()
167167

168-
const listener = tree.addMutationListener((mutation) => {
168+
const listener = tree.addMutationListener((mutation, paths, flushId) => {
169169
/*
170-
{
170+
mutation: {
171171
method: "set",
172172
path: "foo",
173173
args: ["bar2"]
174174
}
175+
paths: Set(["foo"])
176+
flushId: 1
175177
*/
176178
})
177179

@@ -181,6 +183,8 @@ tree.clearMutationTracking()
181183
listener.dispose()
182184
```
183185

186+
It is important here to check the **paths** argument for a list of all paths possibly changed. Reason is that a single mutation might cause changes to multiple paths.
187+
184188
## Dynamic state values
185189

186190
If you insert a function into the state tree it will be called when accessed. The function is passed the **proxy-state-tree** instance and the path of where the function lives in the tree.

packages/node_modules/proxy-state-tree/src/index.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,14 @@ describe('TRACKING', () => {
6969
state.foo
7070
tree.clearPathsTracking(trackId)
7171

72-
tree.addMutationListener((mutation, flushId) => {
72+
tree.addMutationListener((mutation, paths, flushId) => {
7373
reactionCount++
7474
expect(mutation).toEqual({
7575
method: 'set',
7676
path: 'foo',
7777
args: ['bar2'],
7878
})
79+
expect(paths).toEqual(new Set(['foo']))
7980
expect(flushId).toBe(1)
8081
})
8182
tree.startMutationTracking()

packages/node_modules/proxy-state-tree/src/index.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ export type Mutation = {
1212
args: any[]
1313
}
1414

15+
export type MutationCallback = (
16+
mutation: Mutation,
17+
paths: Set<string>,
18+
flushId: number
19+
) => void
20+
1521
let hasWarnedFlushWhileTracking = false
1622

1723
class ProxyStateTree {
@@ -24,7 +30,7 @@ class ProxyStateTree {
2430
private status: Set<STATUS> = new Set()
2531
private currentFlushId: number = 0
2632
private completedTrackingCallbacks = []
27-
private mutationCallbacks = []
33+
private mutationCallbacks: MutationCallback[] = []
2834
private proxy: any
2935
constructor(private state: object, private options: Options = {}) {
3036
if (!isPlainObject(state)) {
@@ -41,8 +47,10 @@ class ProxyStateTree {
4147
}
4248
private addMutation(mutation: Mutation) {
4349
this.currentMutations.push(mutation)
50+
const paths = new Set([...this.objectChanges, mutation.path])
51+
4452
for (let cb of this.mutationCallbacks) {
45-
cb(mutation, this.currentFlushId + 1)
53+
cb(mutation, paths, this.currentFlushId + 1)
4654
}
4755
}
4856
get() {
@@ -145,7 +153,7 @@ class ProxyStateTree {
145153

146154
return pathSet
147155
}
148-
addMutationListener(cb: (mutation: Mutation, flushId: number) => void) {
156+
addMutationListener(cb: MutationCallback) {
149157
const index = this.mutationCallbacks.push(cb) - 1
150158

151159
return () => {

0 commit comments

Comments
 (0)