Last active
          January 8, 2017 13:54 
        
      - 
      
 - 
        
Save RashadSaleh/32dfed51b6c0435794cd65f2a3e45458 to your computer and use it in GitHub Desktop.  
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | import * as storage from 'store'; | |
| import Intercom from 'intercom.js'; | |
| import _ from 'lodash'; | |
| var intercom = Intercom.getInstance(); | |
| var compare = function (a, b) { | |
| var result = { | |
| different: [], | |
| missing_from_first: [], | |
| missing_from_second: [] | |
| }; | |
| _.reduce(a, function (result, value, key) { | |
| if (!a[key]) return result; | |
| if (!b) { | |
| result.missing_from_second.push(key); | |
| return result; | |
| } | |
| if (b[key]) { | |
| if (_.isEqual(value, b[key])) { | |
| return result; | |
| } else { | |
| if (typeof (a[key]) != typeof ({}) || typeof (b[key]) != typeof ({})) { | |
| //dead end. | |
| result.different.push(key); | |
| return result; | |
| } else { | |
| var deeper = compare(a[key], b[key]); | |
| result.different = result.different.concat(_.map(deeper.different, (sub_path) => { | |
| return key + "." + sub_path; | |
| })); | |
| result.missing_from_second = result.missing_from_second.concat(_.map(deeper.missing_from_second, (sub_path) => { | |
| return key + "." + sub_path; | |
| })); | |
| result.missing_from_first = result.missing_from_first.concat(_.map(deeper.missing_from_first, (sub_path) => { | |
| return key + "." + sub_path; | |
| })); | |
| return result; | |
| } | |
| } | |
| } else { | |
| result.missing_from_second.push(key); | |
| return result; | |
| } | |
| }, result); | |
| _.reduce(b, function (result, value, key) { | |
| if (!b[key]) return result; | |
| if (!a) { | |
| result.missing_from_first.push(key); | |
| return result; | |
| } | |
| if (a[key]) { | |
| return result; | |
| } else { | |
| result.missing_from_first.push(key); | |
| return result; | |
| } | |
| }, result); | |
| return result; | |
| } | |
| export default function persist(paths) { | |
| return function (store) { | |
| store.replaceState(_.mergeWith(_.cloneDeep(store.state), storage.get('state'), function (o, s) { | |
| if (s == undefined) return null; | |
| else return undefined; | |
| })); | |
| for (let path of paths.includes) { | |
| intercom.on(path.path + " was set", function (payload) { | |
| let state = payload.state; | |
| let n = payload.new; | |
| let o = payload.old; | |
| store.replaceState(state); | |
| if (path.reactions) { | |
| if (path.reactions.on_set) { | |
| for (let reaction of path.reactions.on_set) { | |
| reaction(store, n, o); | |
| } | |
| } | |
| } | |
| }); | |
| intercom.on(path.path + " was changed", function (payload) { | |
| let state = payload.state; | |
| let n = payload.new; | |
| let o = payload.old; | |
| store.replaceState(state); | |
| if (path.reactions) { | |
| if (path.reactions.on_change) { | |
| for (let reaction of path.reactions.on_change) { | |
| reaction(store, n, o); | |
| } | |
| } | |
| } | |
| }); | |
| intercom.on(path.path + " was unset", function (payload) { | |
| let state = payload.state; | |
| let n = payload.new; | |
| let o = payload.old; | |
| store.replaceState(state); | |
| if (path.reactions.on_unset) { | |
| if (path.reactions) { | |
| for (let reaction of path.reactions.on_unset) { | |
| reaction(store, n, o); | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| store.subscribe((mutation, state) => { | |
| let _state = storage.get('state'); | |
| let c = compare(_state, state); | |
| //persist. | |
| storage.transact('state', (entry) => { | |
| for (let path of paths.includes) { | |
| _.set(entry, path.path, _.get(state, path.path)); | |
| } | |
| }); | |
| for (let path of paths.includes) { | |
| //detect changes | |
| //-------------- | |
| //on set | |
| if (_.includes(c.missing_from_first, path.path)) { | |
| intercom.emit(path.path + ' was set', { | |
| state, | |
| new: _.get(state, path.path), | |
| old: _.get(_state, path.path), | |
| origin: intercom.origin | |
| }); | |
| } | |
| //on change | |
| if (_.includes(c.different, path.path)) { | |
| intercom.emit(path.path + ' was changed', { | |
| state, | |
| new: _.get(state, path.path), | |
| old: _.get(_state, path.path), | |
| origin: intercom.origin | |
| }); | |
| } | |
| //on unset | |
| if (_.includes(c.missing_from_second, path.path)) { | |
| intercom.emit(path.path + ' was unset', { | |
| state, | |
| new: _.get(state, path.path), | |
| old: _.get(_state, path.path), | |
| origin: intercom.origin | |
| }); | |
| } | |
| //-------------- | |
| } | |
| }) | |
| } | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment