@@ -4,7 +4,7 @@ import * as fns from './reactor/fns'
4
4
import { DefaultCache } from './reactor/cache'
5
5
import { NoopLogger , ConsoleGroupLogger } from './logging'
6
6
import { isKeyPath } from './key-path'
7
- import { isGetter } from './getter'
7
+ import { isGetter , getCanonicalKeypathDeps } from './getter'
8
8
import { toJS } from './immutable-helpers'
9
9
import { extend , toFactory } from './utils'
10
10
import {
@@ -60,7 +60,20 @@ class Reactor {
60
60
* @return {* }
61
61
*/
62
62
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 )
64
77
this . reactorState = reactorState
65
78
return result
66
79
}
@@ -95,10 +108,10 @@ class Reactor {
95
108
handler = getter
96
109
getter = [ ]
97
110
}
98
- let { observerState, entry } = fns . addObserver ( this . observerState , getter , handler )
111
+ let { observerState, entry } = fns . addObserver ( this . reactorState , this . observerState , getter , handler )
99
112
this . observerState = observerState
100
113
return ( ) => {
101
- this . observerState = fns . removeObserverByEntry ( this . observerState , entry )
114
+ this . observerState = fns . removeObserverByEntry ( this . reactorState , this . observerState , entry )
102
115
}
103
116
}
104
117
@@ -110,7 +123,7 @@ class Reactor {
110
123
throw new Error ( 'Must call unobserve with a Getter' )
111
124
}
112
125
113
- this . observerState = fns . removeObserver ( this . observerState , getter , handler )
126
+ this . observerState = fns . removeObserver ( this . reactorState , this . observerState , getter , handler )
114
127
}
115
128
116
129
/**
@@ -130,6 +143,7 @@ class Reactor {
130
143
}
131
144
132
145
try {
146
+ this . prevReactorState = this . reactorState
133
147
this . reactorState = fns . dispatch ( this . reactorState , actionType , payload )
134
148
} catch ( e ) {
135
149
this . __isDispatching = false
@@ -171,6 +185,7 @@ class Reactor {
171
185
* @param {Object } stores
172
186
*/
173
187
registerStores ( stores ) {
188
+ this . prevReactorState = this . reactorState
174
189
this . reactorState = fns . registerStores ( this . reactorState , stores )
175
190
this . __notify ( )
176
191
}
@@ -196,6 +211,7 @@ class Reactor {
196
211
* @param {Object } state
197
212
*/
198
213
loadState ( state ) {
214
+ this . prevReactorState = this . reactorState
199
215
this . reactorState = fns . loadState ( this . reactorState , state )
200
216
this . __notify ( )
201
217
}
@@ -210,6 +226,15 @@ class Reactor {
210
226
this . observerState = new ObserverState ( )
211
227
}
212
228
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
+
213
238
/**
214
239
* Notifies all change observers with the current state
215
240
* @private
@@ -220,33 +245,32 @@ class Reactor {
220
245
return
221
246
}
222
247
223
- const dirtyStores = this . reactorState . get ( 'dirtyStores ' )
224
- if ( dirtyStores . size === 0 ) {
225
- return
226
- }
227
-
228
- let observerIdsToNotify = Immutable . Set ( ) . withMutations ( set => {
229
- // notify all observers
230
- set . union ( this . observerState . get ( 'any' ) )
248
+ const keypathsToResolve = this . observerState . get ( 'trackedKeypaths ' )
249
+ const { reactorState , changedKeypaths } = fns . resolveDirtyKeypathStates (
250
+ this . prevReactorState ,
251
+ this . reactorState ,
252
+ keypathsToResolve ,
253
+ true // increment all dirty states (this should leave no unknown state in the keypath tracker map):
254
+ )
255
+ this . reactorState = reactorState
231
256
232
- dirtyStores . forEach ( id => {
233
- const entries = this . observerState . getIn ( [ 'stores' , id ] )
234
- if ( ! entries ) {
235
- return
257
+ // get observers to notify based on the keypaths that changed
258
+ let observersToNotify = Immutable . Set ( ) . withMutations ( set => {
259
+ changedKeypaths . forEach ( keypath => {
260
+ const entries = this . observerState . getIn ( [ 'keypathToEntries' , keypath ] )
261
+ if ( entries && entries . size > 0 ) {
262
+ set . union ( entries )
236
263
}
237
- set . union ( entries )
238
264
} )
239
265
} )
240
266
241
- observerIdsToNotify . forEach ( ( observerId ) => {
242
- const entry = this . observerState . getIn ( [ 'observersMap' , observerId ] )
243
- if ( ! entry ) {
244
- // don't notify here in the case a handler called unobserve on another observer
267
+ observersToNotify . forEach ( ( observer ) => {
268
+ if ( ! this . observerState . get ( 'observers' ) . has ( observer ) ) {
269
+ // the observer was removed in a hander function
245
270
return
246
271
}
247
-
248
- const getter = entry . get ( 'getter' )
249
- const handler = entry . get ( 'handler' )
272
+ const getter = observer . get ( 'getter' )
273
+ const handler = observer . get ( 'handler' )
250
274
251
275
const prevEvaluateResult = fns . evaluate ( this . prevReactorState , getter )
252
276
const currEvaluateResult = fns . evaluate ( this . reactorState , getter )
@@ -257,15 +281,11 @@ class Reactor {
257
281
const prevValue = prevEvaluateResult . result
258
282
const currValue = currEvaluateResult . result
259
283
284
+ // TODO pull some comparator function out of the reactorState
260
285
if ( ! Immutable . is ( prevValue , currValue ) ) {
261
286
handler . call ( null , currValue )
262
287
}
263
288
} )
264
-
265
- const nextReactorState = fns . resetDirtyStores ( this . reactorState )
266
-
267
- this . prevReactorState = nextReactorState
268
- this . reactorState = nextReactorState
269
289
}
270
290
271
291
/**
0 commit comments