Persistence versionning and migrating #178
-
If my state structure changes, I'd like to be able to migrate it on the fly, with any mechanism of my choice. For this i'll need to inject a bit of logic right before the persisting rehydrate to my main state. Are there some ways to do this with legend-state ? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
I solved it by persisting to a new key, and having localstorage-based migration before initializing the persistence (moving Interested to know if there are other patterns. |
Beta Was this translation helpful? Give feedback.
-
The way we suggest to do it is: the This is a way to do it by specifying a version number to be able to define migrations per version. Or you could do it more ad-hoc or per-property by changing property names and detecting the old names. interface V1 {
version: number;
test1: string;
}
interface V2 {
version: number;
test2: string;
}
const obs = observable<V2>({ version: 2, test2: 'hi' });
persistObservable(obs, {
local: {
name: 'store',
adjustData: {
load: (value) => {
if (value.version === 1) {
const old = value as unknown as V1;
// Migrate from v1
value = { version: 2, test2: old.test1 };
}
return value;
},
},
},
}); Alternatively you could do it in a similar way to how you described but by using observables for a bit more structure, rather than parsing local storage yourself: interface V1 {
test1: string;
}
interface V2 {
test2: string;
}
const obs = observable<V2>();
persistObservable(obs, {
local: 'storev2',
});
// If there's nothing saved at the new key
if (!obs.peek()) {
const obsOld = observable<V1>();
const persistOld = persistObservable(obsOld, {
local: 'storev1',
});
const old = obsOld.peek();
if (old) {
obs.set({
test2: old.test1
})
}
// Remove the old key
persistOld.clearLocal();
} |
Beta Was this translation helpful? Give feedback.
The way we suggest to do it is: the
local
property in persistObservable has anadjustData
property which you can use for migration (among other things like encryption). Theload
function runs between loading from storage and setting into the observable, so this will migrate old storage data into the new format you want the observable to use.This is a way to do it by specifying a version number to be able to define migrations per version. Or you could do it more ad-hoc or per-property by changing property names and detecting the old names.