jazz icon indicating copy to clipboard operation
jazz copied to clipboard

Refactor examples to include better migration logic

Open pax-k opened this issue 1 year ago • 3 comments

Something like

export class UserAccount extends Account {
    profile = co.ref(Profile)
    root = co.ref(UserRoot)

    migrate(this: UserAccount, creationProps?: { name: string; avatarUrl?: string }) {
        if (!this._refs.root && creationProps) {
            this.initialMigration(creationProps);
        }

        // Check the current version and run subsequent migrations
        if (this._refs.root) {
            const currentVersion = this.root.version || 0;
            if (currentVersion < 1) {
                this.migrationV1();
            }
            // Uncomment this to run another migration in the future
            // if (currentVersion < 2) {
            //    this.migrationV2();
            //}
            // Add more version checks and migrations as needed
        }
    }

    private initialMigration(creationProps: { name: string; avatarUrl?: string }) {
        super.migrate(creationProps);

        this.root = UserRoot.create(
            {
                // ...
                version: 0  // Set initial version
            },
            { owner: this }
        );
    }

    private migrationV1() {
        // Implement your first schema change here
        // Then increment the version
        this.root!.version = 1;
    }

    private migrationV2() {
        // Implement your second schema change here
        // Then increment the version
        this.root!.version = 2;
    }
}

pax-k avatar Sep 11 '24 13:09 pax-k

trying to parse how this works (I haven't used jazz, just skimming the code):

is the idea that UserRoot holds all covalues in my app, and when displayings things, and I guard any rendering/read of covalues on version != my version?

r5h avatar Sep 29 '24 00:09 r5h

trying to parse how this works (I haven't used jazz, just skimming the code):

is the idea that UserRoot holds all covalues in my app, and when displayings things, and I guard any rendering/read of covalues on version != my version?

yes UserRoot typically holds all CoValues that belong to a user. The way migrations work is that they are run every time you sign up / log in / create a context - so this is your chance to arbitrarily modify the CoValues to support new features, before the app gets a hold of them.

The versioning @pax-k is using here is a manual pattern to keep track of which migrations you have run, you could also have simpler checks for presence/absence of certain fields.

aeplay avatar Sep 30 '24 10:09 aeplay

Interesting! How does this resolve the issues people normally talk about with CRDT migrations (e.g. in the automerge docs)?

A classic issue is a client on an older version (V1) doing an edit to a migrated (by another client) document (V2). How would that be resolved in this case?

Maybe the hope/idea is that user accounts can only be edited by a single client? or maybe there's some way to block clients from syncing until they've migrated?

r5h avatar Oct 06 '24 01:10 r5h