c3lf-system-3/web/src/persistent-state-plugin/index.js
2024-06-22 20:56:51 +02:00

71 lines
No EOL
2.8 KiB
JavaScript

import {isProxy, toRaw} from 'vue';
export default (config) => (store) => {
if (!('isLoadedKey' in config)) {
throw new Error("isLoadedKey not defined in config");
}
const initialize = () => {
config.state.forEach(k => {
try {
if (config.debug) console.log("localStorage init", k, localStorage.getItem(config.prefix + k));
const parsed = JSON.parse(localStorage.getItem(config.prefix + k));
if (parsed !== store.state[k] && parsed !== null) {
store.state[k] = parsed;
} else {
if (config.debug) console.log("localStorage not loaded", k, localStorage.getItem(config.prefix + k));
}
} catch (e) {
if (config.debug) console.log("localStorage parse error", k, e);
}
});
store.state[config.isLoadedKey] = true;
}
const reload = initialize;
if (store.state[config.isLoadedKey] !== true)
initialize();
addEventListener('storage', reload);
if ('state' in config) {
config.state.forEach((member) => {
store.watch((state, getters) => state[member], (newValue, oldValue) => {
try {
if (config.debug) console.log('watch', member,
isProxy(newValue) ? toRaw(newValue) : newValue,
isProxy(oldValue) ? toRaw(oldValue) : oldValue);
const key = config.prefix + member;
const encoded = JSON.stringify(isProxy(newValue) ? toRaw(newValue) : newValue);
if (encoded !== localStorage.getItem(key)) {
if (config.debug) console.log("localStorage replace", member, localStorage.getItem(key), encoded);
if (newValue === null)
localStorage.removeItem(key);
else
localStorage.setItem(key, encoded);
} else {
if (config.debug) console.log("localStorage not saved", member, localStorage.getItem(key), encoded);
}
} catch (e) {
if (config.debug) console.log("localsorage save error", member, e);
}
});
});
}
if ('clearingMutation' in config) {
store.subscribe((mutation, state) => {
if (mutation.type === config.clearingMutation) {
removeEventListener('storage', reload)
for (let key in config.state) {
localStorage.removeItem(config.prefix + key);
}
for (let key in config.state) {
store.state[key] = null;
}
addEventListener('storage', reload)
}
});
}
};