Skip to content
Next Next commit
still something wrong
  • Loading branch information
lyonlai committed Oct 31, 2015
commit 424db11bf2fb6fcc06124f89e4e5c7bf1b8b3fa2
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "nuclear-js",
"version": "1.1.2",
"description": "Immutable, reactive Flux architecture. UI Agnostic.",
"main": "dist/nuclear.js",
"main": "src/main.js",
"scripts": {
"test": "grunt ci"
},
Expand Down
19 changes: 8 additions & 11 deletions src/reactor.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class Reactor {
return
}

let observerIdsToNotify = Immutable.Set().withMutations(set => {
let gettersToNotify = Immutable.Set().withMutations(set => {
// notify all observers
set.union(this.observerState.get('any'))

Expand All @@ -208,15 +208,8 @@ class Reactor {
})
})

observerIdsToNotify.forEach((observerId) => {
const entry = this.observerState.getIn(['observersMap', observerId])
if (!entry) {
// don't notify here in the case a handler called unobserve on another observer
return
}

const getter = entry.get('getter')
const handler = entry.get('handler')
gettersToNotify.forEach((getterId) => {
const getter = this.observerState.get('getters')[getterId];

const prevEvaluateResult = fns.evaluate(this.prevReactorState, getter)
const currEvaluateResult = fns.evaluate(this.reactorState, getter)
Expand All @@ -225,7 +218,11 @@ class Reactor {
const currValue = currEvaluateResult.result

if (!Immutable.is(prevValue, currValue)) {
handler.call(null, currValue)
const handlers = this.observerState.getIn(['gettersMap', getterId])
.map(observerId => this.observerState.getIn(['observersMap', observerId, 'handler']))
// don't notify here in the case a handler called unobserve on another observer

handlers.forEach(handler => handler.call(null, currValue))
}
})

Expand Down
125 changes: 83 additions & 42 deletions src/reactor/fns.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,45 +156,73 @@ exports.loadState = function(reactorState, state) {
*/
exports.addObserver = function(observerState, getter, handler) {
// use the passed in getter as the key so we can rely on a byreference call for unobserve
const getterKey = getter
if (isKeyPath(getter)) {
getter = fromKeyPath(getter)
}
try {
const getterKey = getter
if (isKeyPath(getter)) {
getter = fromKeyPath(getter)
}

const currId = observerState.get('nextId')
const storeDeps = getStoreDeps(getter)
const entry = Immutable.Map({
id: currId,
storeDeps: storeDeps,
getterKey: getterKey,
getter: getter,
handler: handler,
})
const currId = observerState.get('nextId')
const storeDeps = getStoreDeps(getter)
const entry = Immutable.Map({
id: currId,
storeDeps: storeDeps,
getterKey: getterKey,
getter: getter,
handler: handler,
})

let updatedObserverState
if (storeDeps.size === 0) {
// no storeDeps means the observer is dependent on any of the state changing
updatedObserverState = observerState.update('any', observerIds => observerIds.add(currId))
} else {
updatedObserverState = observerState.withMutations(map => {
storeDeps.forEach(storeId => {
let path = ['stores', storeId]
if (!map.hasIn(path)) {
map.setIn(path, Immutable.Set([]))
}
map.updateIn(['stores', storeId], observerIds => observerIds.add(currId))
let updatedObserverState

let existingGetters = observerState.get('getters');

let getterId = existingGetters.indexOf(getter);

if (getterId < 0) {
existingGetters.push(getter);
getterId = existingGetters.length - 1;
}
//update getterMap

let observerIdsForGetter = observerState.getIn(['gettersMap', getterId])

if (!observerIdsForGetter) {
observerIdsForGetter = Immutable.Set([])
}

observerIdsForGetter = observerIdsForGetter.add(currId);

updatedObserverState = observerState.setIn(['gettersMap', getterId], observerIdsForGetter);

if (storeDeps.size === 0) {
// no storeDeps means the observer is dependent on any of the state changing

updatedObserverState = updatedObserverState.updateIn(['any'], getters => getters.add(getterId))
} else {
updatedObserverState = updatedObserverState.withMutations(map => {
storeDeps.forEach(storeId => {
let path = ['stores', storeId]
if (!map.hasIn(path)) {
map.setIn(path, Immutable.Set([]))
}
map.updateIn(['stores', storeId], getters => getters.add(getterId))
})
})
})
}
}

updatedObserverState = updatedObserverState
.set('nextId', currId + 1)
.setIn(['observersMap', currId], entry)
updatedObserverState = updatedObserverState
.set('nextId', currId + 1)
.setIn(['observersMap', currId], entry)

return {
observerState: updatedObserverState,
entry: entry,
return {
observerState: updatedObserverState,
entry: entry,
}
} catch (e) {
debugger;
}


}

/**
Expand Down Expand Up @@ -239,18 +267,31 @@ exports.removeObserver = function(observerState, getter, handler) {
*/
exports.removeObserverByEntry = function(observerState, entry) {
return observerState.withMutations(map => {
const id = entry.get('id')
const storeDeps = entry.get('storeDeps')
try {
const id = entry.get('id')
const getter = entry.get('getter')
const storeDeps = entry.get('storeDeps')

if (storeDeps.size === 0) {
map.update('any', anyObsevers => anyObsevers.remove(id))
} else {
storeDeps.forEach(storeId => {
map.updateIn(['stores', storeId], observers => observers.remove(id))
})
const existingGetters = observerState.get('getters');

const getterId = existingGetters.indexOf(getter);

//cleaning the gettersMap
map.updateIn(['gettersMap', getterId], observerIds => observerIds.remove(id));

if (storeDeps.size === 0 && map.getIn(['gettersMap', getterId]).size === 0) {
map.update('any', anyGetters => anyGetters.remove(getterId))
} else {
storeDeps.forEach(storeId => {
map.updateIn(['stores', storeId], getters => getters.remove(getterId))
})
}

map.removeIn(['observersMap', id])
} catch (e) {
debugger;
}

map.removeIn(['observersMap', id])
})
}

Expand Down
8 changes: 6 additions & 2 deletions src/reactor/records.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@ const ReactorState = Immutable.Record({
})

const ObserverState = Immutable.Record({
// observers registered to any store change
// getters registered to any store change
any: Immutable.Set([]),
// observers registered to specific store changes
// getters registered to specific store changes
stores: Immutable.Map({}),

getters: [],

gettersMap: Immutable.Map({}),

observersMap: Immutable.Map({}),

nextId: 1,
Expand Down