Support for migrations
See original GitHub issueFeature request
I’ve been thinking about how I could make the usage of slate in production easier for me (and possibly others). The thing is:
- There are quite a few breaking changes.
In terms of code, I don’t mind it that much. Yeah, it’s a pain and it’s all for a good reason. I am fine with that.
- These breaking changes often change the structure of the editor state.
Now, this, in my opinion, is a problem. The state is often persisted in various storage (server/client side) and as a result of these changes, companies, especially the ones that have a lot of data, can run into trouble. Also, it is not always clear how and when the state structure changed. Yes there is the changelog which is extremely useful, but it requires some serious time to investigate and act on these changes. I am suggesting a way to potentially mitigate this: Create slate-migrations package This package would simply contain a folder migrations, and for each braking change in the state, a new migration would be created and placed in this folder. The interface for a migration could look something like:
export interface Migration {
// Semver range
fromVersionRange: string;
// Semver single version
toVersion: string;
migrate: (value: any) => any;
}
Notice the ‘any’ for value, we obviously can’t strongly type migrations as it would reference a code that could have changed in the meantime. Slate could then take an extra field ‘migrations’ which would be an array of migrations. The state of the editor would have to change from an array of nodes to an object in order to keep the version in it. So:
{
version: '0.52.2',
children: Node[]
}
Would effectively become the value of the editor. The version could be picked up from the package version of slate.
When first initialized, the Slate could look at the version and the migrations field, try to migrate and if it succeeds, it would then use the migration chain to migrate the value to the most recent state.
It would be fully up to users to include as many migrations as they want (if any).
I have previously successfully implemented something like this here:
https://github.com/react-page/react-page/pull/554#issuecomment-413847279 It also contains some pseudo-code on how the migrations would work.
I’d like to know what you all think about this. Please note that while this is an extra package, and some extra code, the maintenance would be minimal, as migrations are pretty much ‘create once and never touch again’ kind of thing. The added responsibility of creating migrations might suck a little bit, but it has great value for users. Also to create migrations is actually not too much work. Check for instance the migrations here: https://github.com/react-page/react-page/tree/master/packages/plugins/content/slate/src/migrations these actually handle the changed slate state for versions around 40 (I don’t remember which exactly). Also if we have the information of the version on the state, we can gracefully fail and provide information on the reason for the failure if it failed because the state is incompatible.
I am happy to implement this functionality but before I start the work, I want to make sure it’s ok with everybody here.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:9
- Comments:14 (4 by maintainers)
Top GitHub Comments
@oyeanuj Nothing freestanding that can be used solely by slate, but you can check https://github.com/react-page/react-page/tree/b6c83a8650cfe9089e0c3eaf471ab58a0f7db761/packages/plugins/content/slate/src/migrations for an example of migrations and https://github.com/react-page/react-page/blob/db777ca3df54b3547adf7f6b3b9988bc63f1b7da/packages/core/src/service/plugin/classes.ts searching for “migration” for implementation. Not sure if that helps but it’s the best I have 😃
Thanks Ian. I think I can figure out some sort of combination of both, but for the time being, I guess the shim will be enough.