@@ -4,7 +4,7 @@ import * as fns from './reactor/fns'
4
4
import { DefaultCache } from './reactor/cache'
5
5
import { 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,36 +245,36 @@ 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
248
fns . getLoggerFunction ( this . reactorState , 'notifyStart' ) ( this . reactorState , this . observerState )
229
249
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
233
258
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 )
238
265
}
239
- set . union ( entries )
240
266
} )
241
267
} )
242
268
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
247
272
return
248
273
}
249
274
let didCall = false
250
275
251
- const getter = entry . get ( 'getter' )
252
- const handler = entry . get ( 'handler' )
276
+ const getter = observer . get ( 'getter' )
277
+ const handler = observer . get ( 'handler' )
253
278
254
279
fns . getLoggerFunction ( this . reactorState , 'notifyEvaluateStart' ) ( this . reactorState , getter )
255
280
@@ -262,18 +287,14 @@ class Reactor {
262
287
const prevValue = prevEvaluateResult . result
263
288
const currValue = currEvaluateResult . result
264
289
290
+ // TODO pull some comparator function out of the reactorState
265
291
if ( ! Immutable . is ( prevValue , currValue ) ) {
266
292
handler . call ( null , currValue )
267
293
didCall = true
268
294
}
269
295
fns . getLoggerFunction ( this . reactorState , 'notifyEvaluateEnd' ) ( this . reactorState , getter , didCall , currValue )
270
296
} )
271
297
272
- const nextReactorState = fns . resetDirtyStores ( this . reactorState )
273
-
274
- this . prevReactorState = nextReactorState
275
- this . reactorState = nextReactorState
276
-
277
298
fns . getLoggerFunction ( this . reactorState , 'notifyEnd' ) ( this . reactorState , this . observerState )
278
299
}
279
300
0 commit comments