Skip to content

Instantly share code, notes, and snippets.

@mironal
Created September 9, 2018 23:30
Show Gist options
  • Select an option

  • Save mironal/c17fc25ffeed3081962c9359c6cba90a to your computer and use it in GitHub Desktop.

Select an option

Save mironal/c17fc25ffeed3081962c9359c6cba90a to your computer and use it in GitHub Desktop.
persist plugin for @rematch
import { Plugin } from "@rematch/core"
export interface PersistConfig {
whitelist: string[]
version?: number
delay?: number
debug?: boolean
}
export let persistor: { purge(): void }
const persistPlugin = (config: PersistConfig): Plugin => {
if (persistor) {
throw new Error(
"Currently only one instance of persistPlugin can be created.",
)
}
const { whitelist, debug, version, delay } = config
let merged = {}
const rootKey = `persist:root-${version || -1}`
const debugLog =
debug && process.env.NODE_ENV !== "production"
? // tslint:disable-next-line:no-console
console.debug
: (message?: any, ...optionalParams: any[]) => {
/*NOOP*/
}
let timerHandler: number | undefined
const storeLazy = () => {
if (timerHandler) {
debugLog("persist:cancel:store")
clearTimeout(timerHandler)
timerHandler = undefined
}
timerHandler = window.setTimeout(() => {
storeImmediate()
}, delay || 1000)
}
const storeImmediate = () => {
if (timerHandler) {
debugLog("persist:cancel:store")
clearTimeout(timerHandler)
timerHandler = undefined
}
debugLog("persist:store")
localStorage.setItem(rootKey, JSON.stringify(merged))
}
persistor = {
purge: () => {
localStorage.removeItem(rootKey)
merged = {}
},
}
return {
onInit() {
const str = localStorage.getItem(rootKey)
if (str) {
try {
const obj = JSON.parse(str)
debugLog("persist:restore", obj)
merged = obj
} catch (e) {
// tslint:disable-next-line:no-console
console.error("persist:restore", e)
localStorage.removeItem(rootKey)
}
}
},
onModel(model) {
const { name } = model
const obj = merged[name]
if (obj) {
debugLog("persist:initialize state", name, obj)
model.state = obj
}
},
middleware: store => next => action => {
const { type } = action
if (typeof type === "string") {
const key = whitelist.find(w => type.startsWith(w))
if (key) {
const nextState = next(action)
const after = store.getState()
merged = { ...merged, [key]: after[key] || {} }
debugLog("persist:schedule:store", key, after[key])
storeLazy()
return nextState
}
}
return next(action)
},
}
}
export default persistPlugin
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment