Open sisp opened 4 years ago
That's why "fromSnapshot" in models are there.
E.g.
// first version
@model("...")
class M extends Model({
}) {
_version: prop(1)
fullName: prop<string>()
} {}
// second version
@model("...")
class M extends Model({
}) {
_version: prop(2)
firstName: prop<string>(),
lastName: prop<string>()
} {
fromSnapshot(maybeOldSnapshot: any) {
if (maybeOldSnapshot._version >= 2) {
return maybeOldSnapshot // up to date
}
// update to latest
return {
_version: 2,
firstName: maybeOldSnapshot.fullName.split(" ")[0],
lastName: maybeOldSnapshot.fullName.split(" ")[1],
}
}
}
That way whenever an old snapshot is loaded with fromSnapshot(...)
it will be updated to the latest version.
Also this way parent models don't have to worry about the versioning of its children, just about their own.
I implemented some kind of persist library with built-in support for migrations for mobx-state-tree.
The idea here is to have serialize
, deserialize
and migrate
methods in each migration.
The serialize
defines how to transform data from the snapshot to JSON. The main mission of it is resolving all the references, for example, I'm storing part of the store where I'm using some reference, in serialize
I'm finding the exact entity and storing it too.
The deserialize
doing vise-versa.
And the migrate
transforming snapshot from v1 to v2. I'm storing the last migration index in the local store. It's pretty the same thing we do on the backend side. Each migration migrate snapshot.
With mobx-keystone, it should work even better since we have the exact model name inside each entry in the snapshot, so it might help to resolve and work with it.
See #326 for the latest API related to versioning.
@xaviergonz, regarding https://github.com/xaviergonz/mobx-keystone/issues/52#issuecomment-538323617:
is there a preferred, canonical way to handle more complex scenarios?
I've been thinking how to deal with model versioning. The scenario I'm looking at is saving a snapshot of the current state in local storage, so when the browser is closed and re-opened (or the app is reloaded), the previous state is automatically loaded again. All is good as long as the state layout does not change. But what happens when a snapshot is saved, I change a model class (or multiple model classes, or the entire state layout), re-deploy the app, and then the snapshot, which has the old layout, is loaded by the new state implementation? A way to migrate from one/any (old) snapshot version to the current version is needed, I think.
A couple of questions I've been asking myself:
fromSnapshot
method?