Created
September 24, 2018 21:32
-
-
Save terrysahaidak/43f316d278f8519538e69e7fd2c737a3 to your computer and use it in GitHub Desktop.
Mobx-state-tree persist
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 { applySnapshot, onSnapshot } from 'mobx-state-tree'; | |
import { transaction } from 'mobx'; | |
import { AsyncStorage } from 'react-native'; | |
const getSnapshots = (storesList, storage) => { | |
const promises = storesList.map(storeName => | |
storage.getItem(storeName), | |
); | |
return Promise.all(promises).then(snapshots => | |
snapshots.reduce((acc, current, index) => { | |
const storeName = storesList[index]; | |
acc[storeName] = JSON.parse(current); | |
return acc; | |
}, {}), | |
); | |
}; | |
const removeSnapshots = (storesList, storage) => { | |
const promises = storesList.map(storeName => | |
storage.removeItem(storeName), | |
); | |
return Promise.all(promises); | |
}; | |
const rehydrateOrApplySnapshot = (store, snapshot) => { | |
if (!snapshot) return; | |
if (typeof store.rehydrate === 'function') { | |
store.rehydrate(snapshot); | |
} else { | |
applySnapshot(store, snapshot); | |
} | |
}; | |
const purgeStore = ([, store]) => { | |
if (typeof store.purge === 'function') { | |
store.purge(); | |
} else { | |
applySnapshot(store, {}); | |
} | |
}; | |
const attachSnapshotListeners = (stores, storage) => { | |
stores.forEach(([name, store]) => | |
onSnapshot(store, snapshot => | |
storage.setItem(name, JSON.stringify(snapshot)), | |
), | |
); | |
}; | |
const createRehydrate = (storeEntries, storage) => () => { | |
const storesList = storeEntries.map(i => i[0]); | |
getSnapshots(storesList, storage).then(snapshots => | |
transaction(() => | |
storeEntries.forEach(([name, store]) => { | |
const snapshot = snapshots[name]; | |
rehydrateOrApplySnapshot(store, snapshot); | |
}), | |
), | |
); | |
}; | |
const createPurge = (storeEntries, storage) => () => { | |
const storesList = storeEntries.map(i => i[0]); | |
removeSnapshots(storesList, storage).then(() => | |
transaction(() => storeEntries.forEach(purgeStore)), | |
); | |
}; | |
const createPersist = (stores, config = {}) => { | |
let entries = Object.entries(stores); | |
const storage = config.storage || AsyncStorage; | |
if (config.whitelist) { | |
entries = entries.filter(([name]) => | |
config.whitelist.includes(name), | |
); | |
} | |
attachSnapshotListeners(entries, storage); | |
const rehydrate = createRehydrate(entries, storage); | |
const purge = createPurge(entries, storage); | |
return { | |
rehydrate, | |
purge, | |
}; | |
}; | |
export default createPersist; |
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 RootStore from './RootStore'; | |
import createPersist from './persist/createPersist'; | |
const createStores = () => { | |
const persist = createPersist(RootStore, { | |
whitelist: ['currentUser', 'ui'], | |
}); | |
// returns a promise, wait for rehydration if you want to | |
persist.rehydrate(); | |
// or clean saved data | |
// persist.purge(); | |
return RootStore; | |
}; | |
export default createStores; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment