Skip to content

Commit 2d6865f

Browse files
committed
Refactor ObseverState to be mutable
1 parent e90a721 commit 2d6865f

7 files changed

+428
-444
lines changed

src/reactor.js

+34-52
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import Immutable from 'immutable'
1+
import { Map, is, Set } from 'immutable'
22
import createReactMixin from './create-react-mixin'
33
import * as fns from './reactor/fns'
44
import { DefaultCache } from './reactor/cache'
@@ -7,9 +7,9 @@ import { isKeyPath } from './key-path'
77
import { isGetter, getCanonicalKeypathDeps } from './getter'
88
import { toJS } from './immutable-helpers'
99
import { extend, toFactory } from './utils'
10+
import ObserverState from './reactor/observer-state'
1011
import {
1112
ReactorState,
12-
ObserverState,
1313
DEBUG_OPTIONS,
1414
PROD_OPTIONS,
1515
} from './reactor/records'
@@ -45,8 +45,6 @@ class Reactor {
4545
this.reactorState = initialReactorState
4646
this.observerState = new ObserverState()
4747

48-
this.observerState = this.observerState.asMutable()
49-
5048
this.ReactMixin = createReactMixin(this)
5149

5250
// keep track of the depth of batch nesting
@@ -62,21 +60,22 @@ class Reactor {
6260
* @return {*}
6361
*/
6462
evaluate(keyPathOrGetter) {
65-
// look through the keypathStates and see if any of the getters dependencies are dirty, if so resolve
66-
// against the previous reactor state
67-
let updatedReactorState = this.reactorState
68-
if (!isKeyPath(keyPathOrGetter)) {
69-
const maxCacheDepth = fns.getOption(updatedReactorState, 'maxCacheDepth')
70-
let res = fns.resolveDirtyKeypathStates(
71-
this.prevReactorState,
72-
this.reactorState,
73-
getCanonicalKeypathDeps(keyPathOrGetter, maxCacheDepth)
74-
)
75-
updatedReactorState = res.reactorState
76-
}
63+
let result
64+
65+
this.reactorState = this.reactorState.withMutations(reactorState => {
66+
if (!isKeyPath(keyPathOrGetter)) {
67+
// look through the keypathStates and see if any of the getters dependencies are dirty, if so resolve
68+
// against the previous reactor state
69+
const maxCacheDepth = fns.getOption(reactorState, 'maxCacheDepth')
70+
fns.resolveDirtyKeypathStates(
71+
this.prevReactorState,
72+
reactorState,
73+
getCanonicalKeypathDeps(keyPathOrGetter, maxCacheDepth)
74+
)
75+
}
76+
result = fns.evaluate(reactorState, keyPathOrGetter)
77+
})
7778

78-
let { result, reactorState } = fns.evaluate(updatedReactorState, keyPathOrGetter)
79-
this.reactorState = reactorState
8079
return result
8180
}
8281

@@ -110,9 +109,9 @@ class Reactor {
110109
handler = getter
111110
getter = []
112111
}
113-
let entry = fns.addObserver(this.reactorState, this.observerState, getter, handler)
112+
const entry = this.observerState.addObserver(this.reactorState, getter, handler)
114113
return () => {
115-
fns.removeObserverByEntry(this.reactorState, this.observerState, entry)
114+
this.observerState.removeObserverByEntry(this.reactorState, entry)
116115
}
117116
}
118117

@@ -124,7 +123,7 @@ class Reactor {
124123
throw new Error('Must call unobserve with a Getter')
125124
}
126125

127-
fns.removeObserver(this.reactorState, this.observerState, getter, handler)
126+
this.observerState.removeObserver(this.reactorState, getter, handler)
128127
}
129128

130129
/**
@@ -227,15 +226,6 @@ class Reactor {
227226
this.observerState = new ObserverState()
228227
}
229228

230-
/**
231-
* Denotes a new state, via a store registration, dispatch or some other method
232-
* Resolves any outstanding keypath states and sets a new reactorState
233-
* @private
234-
*/
235-
__nextState(newState) {
236-
// TODO(jordan): determine if this is actually needed
237-
}
238-
239229
/**
240230
* Notifies all change observers with the current state
241231
* @private
@@ -246,29 +236,24 @@ class Reactor {
246236
return
247237
}
248238

239+
this.prevReactorState = this.prevReactorState.asMutable()
240+
this.reactorState = this.reactorState.asMutable()
241+
249242
fns.getLoggerFunction(this.reactorState, 'notifyStart')(this.reactorState, this.observerState)
250243

251-
const keypathsToResolve = this.observerState.get('trackedKeypaths')
252-
const { reactorState, changedKeypaths } = fns.resolveDirtyKeypathStates(
244+
const keypathsToResolve = this.observerState.getTrackedKeypaths()
245+
const changedKeypaths = fns.resolveDirtyKeypathStates(
253246
this.prevReactorState,
254247
this.reactorState,
255248
keypathsToResolve,
256249
true // increment all dirty states (this should leave no unknown state in the keypath tracker map):
257250
)
258-
this.reactorState = reactorState
259251

260252
// get observers to notify based on the keypaths that changed
261-
let observersToNotify = Immutable.Set().withMutations(set => {
262-
changedKeypaths.forEach(keypath => {
263-
const entries = this.observerState.getIn(['keypathToEntries', keypath])
264-
if (entries && entries.size > 0) {
265-
set.union(entries)
266-
}
267-
})
268-
})
253+
const observersToNotify = this.observerState.getObserversToNotify(changedKeypaths)
269254

270255
observersToNotify.forEach((observer) => {
271-
if (!this.observerState.get('observers').has(observer)) {
256+
if (!this.observerState.hasObserver(observer)) {
272257
// the observer was removed in a hander function
273258
return
274259
}
@@ -279,23 +264,20 @@ class Reactor {
279264

280265
fns.getLoggerFunction(this.reactorState, 'notifyEvaluateStart')(this.reactorState, getter)
281266

282-
const prevEvaluateResult = fns.evaluate(this.prevReactorState, getter)
283-
const currEvaluateResult = fns.evaluate(this.reactorState, getter)
267+
const prevValue = fns.evaluate(this.prevReactorState, getter)
268+
const currValue = fns.evaluate(this.reactorState, getter)
284269

285-
this.prevReactorState = prevEvaluateResult.reactorState
286-
this.reactorState = currEvaluateResult.reactorState
287-
288-
const prevValue = prevEvaluateResult.result
289-
const currValue = currEvaluateResult.result
290-
291-
// TODO pull some comparator function out of the reactorState
292-
if (!Immutable.is(prevValue, currValue)) {
270+
// TODO(jordan) pull some comparator function out of the reactorState
271+
if (!is(prevValue, currValue)) {
293272
handler.call(null, currValue)
294273
didCall = true
295274
}
296275
fns.getLoggerFunction(this.reactorState, 'notifyEvaluateEnd')(this.reactorState, getter, didCall, currValue)
297276
})
298277

278+
this.prevReactorState = this.prevReactorState.asImmutable()
279+
this.reactorState = this.reactorState.asImmutable()
280+
299281
fns.getLoggerFunction(this.reactorState, 'notifyEnd')(this.reactorState, this.observerState)
300282
}
301283

0 commit comments

Comments
 (0)