@@ -4,7 +4,7 @@ import * as fns from './reactor/fns'
44import { DefaultCache } from './reactor/cache'
55import { ConsoleGroupLogger } from './logging'
66import { isKeyPath } from './key-path'
7- import { isGetter } from './getter'
7+ import { isGetter , getCanonicalKeypathDeps } from './getter'
88import { toJS } from './immutable-helpers'
99import { extend , toFactory } from './utils'
1010import {
@@ -60,7 +60,20 @@ class Reactor {
6060 * @return {* }
6161 */
6262 evaluate ( keyPathOrGetter ) {
63- let { result, reactorState } = fns . evaluate ( this . reactorState , keyPathOrGetter )
63+ // look through the keypathStates and see if any of the getters dependencies are dirty, if so resolve
64+ // against the previous reactor state
65+ let updatedReactorState = this . reactorState
66+ if ( ! isKeyPath ( keyPathOrGetter ) ) {
67+ const maxCacheDepth = fns . getOption ( updatedReactorState , 'maxCacheDepth' )
68+ let res = fns . resolveDirtyKeypathStates (
69+ this . prevReactorState ,
70+ this . reactorState ,
71+ getCanonicalKeypathDeps ( keyPathOrGetter , maxCacheDepth )
72+ )
73+ updatedReactorState = res . reactorState
74+ }
75+
76+ let { result, reactorState } = fns . evaluate ( updatedReactorState , keyPathOrGetter )
6477 this . reactorState = reactorState
6578 return result
6679 }
@@ -95,10 +108,10 @@ class Reactor {
95108 handler = getter
96109 getter = [ ]
97110 }
98- let { observerState, entry } = fns . addObserver ( this . observerState , getter , handler )
111+ let { observerState, entry } = fns . addObserver ( this . reactorState , this . observerState , getter , handler )
99112 this . observerState = observerState
100113 return ( ) => {
101- this . observerState = fns . removeObserverByEntry ( this . observerState , entry )
114+ this . observerState = fns . removeObserverByEntry ( this . reactorState , this . observerState , entry )
102115 }
103116 }
104117
@@ -110,7 +123,7 @@ class Reactor {
110123 throw new Error ( 'Must call unobserve with a Getter' )
111124 }
112125
113- this . observerState = fns . removeObserver ( this . observerState , getter , handler )
126+ this . observerState = fns . removeObserver ( this . reactorState , this . observerState , getter , handler )
114127 }
115128
116129 /**
@@ -130,6 +143,7 @@ class Reactor {
130143 }
131144
132145 try {
146+ this . prevReactorState = this . reactorState
133147 this . reactorState = fns . dispatch ( this . reactorState , actionType , payload )
134148 } catch ( e ) {
135149 this . __isDispatching = false
@@ -171,6 +185,7 @@ class Reactor {
171185 * @param {Object } stores
172186 */
173187 registerStores ( stores ) {
188+ this . prevReactorState = this . reactorState
174189 this . reactorState = fns . registerStores ( this . reactorState , stores )
175190 this . __notify ( )
176191 }
@@ -196,6 +211,7 @@ class Reactor {
196211 * @param {Object } state
197212 */
198213 loadState ( state ) {
214+ this . prevReactorState = this . reactorState
199215 this . reactorState = fns . loadState ( this . reactorState , state )
200216 this . __notify ( )
201217 }
@@ -210,6 +226,15 @@ class Reactor {
210226 this . observerState = new ObserverState ( )
211227 }
212228
229+ /**
230+ * Denotes a new state, via a store registration, dispatch or some other method
231+ * Resolves any outstanding keypath states and sets a new reactorState
232+ * @private
233+ */
234+ __nextState ( newState ) {
235+ // TODO(jordan): determine if this is actually needed
236+ }
237+
213238 /**
214239 * Notifies all change observers with the current state
215240 * @private
@@ -220,36 +245,36 @@ class Reactor {
220245 return
221246 }
222247
223- const dirtyStores = this . reactorState . get ( 'dirtyStores' )
224- if ( dirtyStores . size === 0 ) {
225- return
226- }
227-
228248 fns . getLoggerFunction ( this . reactorState , 'notifyStart' ) ( this . reactorState , this . observerState )
229249
230- let observerIdsToNotify = Immutable . Set ( ) . withMutations ( set => {
231- // notify all observers
232- set . union ( this . observerState . get ( 'any' ) )
250+ const keypathsToResolve = this . observerState . get ( 'trackedKeypaths' )
251+ const { reactorState, changedKeypaths } = fns . resolveDirtyKeypathStates (
252+ this . prevReactorState ,
253+ this . reactorState ,
254+ keypathsToResolve ,
255+ true // increment all dirty states (this should leave no unknown state in the keypath tracker map):
256+ )
257+ this . reactorState = reactorState
233258
234- dirtyStores . forEach ( id => {
235- const entries = this . observerState . getIn ( [ 'stores' , id ] )
236- if ( ! entries ) {
237- return
259+ // get observers to notify based on the keypaths that changed
260+ let observersToNotify = Immutable . Set ( ) . withMutations ( set => {
261+ changedKeypaths . forEach ( keypath => {
262+ const entries = this . observerState . getIn ( [ 'keypathToEntries' , keypath ] )
263+ if ( entries && entries . size > 0 ) {
264+ set . union ( entries )
238265 }
239- set . union ( entries )
240266 } )
241267 } )
242268
243- observerIdsToNotify . forEach ( ( observerId ) => {
244- const entry = this . observerState . getIn ( [ 'observersMap' , observerId ] )
245- if ( ! entry ) {
246- // don't notify here in the case a handler called unobserve on another observer
269+ observersToNotify . forEach ( ( observer ) => {
270+ if ( ! this . observerState . get ( 'observers' ) . has ( observer ) ) {
271+ // the observer was removed in a hander function
247272 return
248273 }
249274 let didCall = false
250275
251- const getter = entry . get ( 'getter' )
252- const handler = entry . get ( 'handler' )
276+ const getter = observer . get ( 'getter' )
277+ const handler = observer . get ( 'handler' )
253278
254279 fns . getLoggerFunction ( this . reactorState , 'notifyEvaluateStart' ) ( this . reactorState , getter )
255280
@@ -262,18 +287,14 @@ class Reactor {
262287 const prevValue = prevEvaluateResult . result
263288 const currValue = currEvaluateResult . result
264289
290+ // TODO pull some comparator function out of the reactorState
265291 if ( ! Immutable . is ( prevValue , currValue ) ) {
266292 handler . call ( null , currValue )
267293 didCall = true
268294 }
269295 fns . getLoggerFunction ( this . reactorState , 'notifyEvaluateEnd' ) ( this . reactorState , getter , didCall , currValue )
270296 } )
271297
272- const nextReactorState = fns . resetDirtyStores ( this . reactorState )
273-
274- this . prevReactorState = nextReactorState
275- this . reactorState = nextReactorState
276-
277298 fns . getLoggerFunction ( this . reactorState , 'notifyEnd' ) ( this . reactorState , this . observerState )
278299 }
279300
0 commit comments