Skip to content

Commit 4020de4

Browse files
feat(proxy-state-tree): add global event listener
1 parent 6384d26 commit 4020de4

File tree

3 files changed

+102
-30
lines changed

3 files changed

+102
-30
lines changed

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,34 @@ listener.dispose()
126126

127127
Here we combine the tracked paths with the mutations performed to see if this components, computed or whatever indeed needs to run again, doing a new **startPathsTracking** and **clearPathsTracking**.
128128

129+
You can optionally declare a global listener which will be informed by all mutations:
130+
131+
```js
132+
import ProxyStateTree from 'proxy-state-tree'
133+
134+
const tree = new ProxyStateTree({
135+
foo: 'bar',
136+
bar: 'baz'
137+
})
138+
const state = tree.get()
139+
140+
const listener = tree.addMutationListener((mutations) => {
141+
/*
142+
[{
143+
method: "set",
144+
path: "foo",
145+
args: ["bar2"]
146+
}]
147+
*/
148+
})
149+
150+
tree.startMutationTracking()
151+
state.foo = 'bar2'
152+
tree.clearMutationTracking()
153+
tree.flush()
154+
listener.dispose()
155+
```
156+
129157
## Dynamic state values
130158

131159
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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,26 @@ describe('REACTIONS', () => {
409409
tree.flush()
410410
expect(reactionCount).toBe(1)
411411
})
412+
test('should be able to register a global listener', () => {
413+
expect.assertions(1)
414+
const tree = new ProxyStateTree({
415+
foo: 'bar',
416+
})
417+
const state = tree.get()
418+
tree.addMutationListener((mutations) => {
419+
expect(mutations).toEqual([
420+
{
421+
method: 'set',
422+
path: 'foo',
423+
args: ['bar2'],
424+
},
425+
])
426+
})
427+
tree.startMutationTracking()
428+
state.foo = 'bar2'
429+
tree.clearMutationTracking()
430+
tree.flush()
431+
})
412432
test('should be able to manually add a path to the current tracking', () => {
413433
let renderCount = 0
414434
const tree = new ProxyStateTree({

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

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class ProxyStateTree {
1616
state: object
1717
options: Options
1818
pathDependencies: object
19+
globalDependencies: Set<Function>
1920
objectChanges: Set<string>
2021
mutations: Mutation[]
2122
currentMutations: Mutation[]
@@ -34,6 +35,7 @@ class ProxyStateTree {
3435
this.state = state
3536
this.options = options
3637
this.pathDependencies = {}
38+
this.globalDependencies = new Set()
3739
this.mutations = []
3840
this.currentMutations = []
3941
this.paths = []
@@ -79,6 +81,10 @@ class ProxyStateTree {
7981
this.mutations.length = 0
8082
this.objectChanges.clear()
8183

84+
for (let globalDependency of this.globalDependencies) {
85+
globalDependency(mutations)
86+
}
87+
8288
return mutations
8389
}
8490
startMutationTracking() {
@@ -125,43 +131,61 @@ class ProxyStateTree {
125131

126132
return pathSet
127133
}
128-
addMutationListener(initialPaths: Set<string>, cb: () => void) {
129-
const pathDependencies = this.pathDependencies
130-
let currentStringPaths = initialPaths
131-
132-
for (let currentStringPath of currentStringPaths) {
133-
pathDependencies[currentStringPath] = pathDependencies[currentStringPath]
134-
? pathDependencies[currentStringPath].add(cb)
135-
: new Set([cb])
136-
}
134+
addMutationListener(cb: (mutations: Mutation[]) => void)
135+
addMutationListener(initialPaths: Set<string>, cb: () => void)
136+
addMutationListener() {
137+
if (arguments.length === 1) {
138+
const cb = arguments[0]
139+
const globalDependencies = this.globalDependencies
140+
globalDependencies.add(cb)
141+
142+
return {
143+
dispose() {
144+
globalDependencies.delete(cb)
145+
},
146+
}
147+
} else {
148+
const initialPaths = arguments[0]
149+
const cb = arguments[1]
150+
const pathDependencies = this.pathDependencies
151+
let currentStringPaths = initialPaths
152+
153+
for (let currentStringPath of currentStringPaths) {
154+
pathDependencies[currentStringPath] = pathDependencies[
155+
currentStringPath
156+
]
157+
? pathDependencies[currentStringPath].add(cb)
158+
: new Set([cb])
159+
}
137160

138-
return {
139-
update(newStringPaths: Set<string>) {
140-
for (let currentStringPath of currentStringPaths) {
141-
if (!newStringPaths.has(currentStringPath)) {
142-
pathDependencies[currentStringPath].delete(cb)
161+
return {
162+
update(newStringPaths: Set<string>) {
163+
for (let currentStringPath of currentStringPaths) {
164+
if (!newStringPaths.has(currentStringPath)) {
165+
pathDependencies[currentStringPath].delete(cb)
166+
}
143167
}
144-
}
145168

146-
for (let newStringPath of newStringPaths) {
147-
if (!currentStringPaths.has(newStringPath)) {
148-
pathDependencies[newStringPath] = pathDependencies[newStringPath]
149-
? pathDependencies[newStringPath].add(cb)
150-
: new Set([cb])
169+
for (let newStringPath of newStringPaths) {
170+
if (!currentStringPaths.has(newStringPath)) {
171+
pathDependencies[newStringPath] = pathDependencies[newStringPath]
172+
? pathDependencies[newStringPath].add(cb)
173+
: new Set([cb])
174+
}
151175
}
152-
}
153176

154-
currentStringPaths = newStringPaths
155-
},
156-
dispose() {
157-
for (let currentStringPath of currentStringPaths) {
158-
pathDependencies[currentStringPath].delete(cb)
177+
currentStringPaths = newStringPaths
178+
},
179+
dispose() {
180+
for (let currentStringPath of currentStringPaths) {
181+
pathDependencies[currentStringPath].delete(cb)
159182

160-
if (pathDependencies[currentStringPath].size === 0) {
161-
delete pathDependencies[currentStringPath]
183+
if (pathDependencies[currentStringPath].size === 0) {
184+
delete pathDependencies[currentStringPath]
185+
}
162186
}
163-
}
164-
},
187+
},
188+
}
165189
}
166190
}
167191
}

0 commit comments

Comments
 (0)