Skip to content

Instantly share code, notes, and snippets.

@RashadSaleh
Last active January 8, 2017 13:54
Show Gist options
  • Save RashadSaleh/32dfed51b6c0435794cd65f2a3e45458 to your computer and use it in GitHub Desktop.
Save RashadSaleh/32dfed51b6c0435794cd65f2a3e45458 to your computer and use it in GitHub Desktop.
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