CRDT insides to generate classes, which uses crdt under the hood from a schema language

Hi,

and I am currently researching the possibility of defining a schema, like the grpc or the prisma.io has, to generate ts/js classes or a target language, which uses Crdts under the hood to sync client and server.

The general problem is:

Developing an app, which needs to sync to server. The app should work offline. Then there are different type of apps mobile, Web and Desktop and those in different languages. Nobody wants to write the sync protocol by hand and rewrite it, when the model changes.

I posted a request to https://github.com/peer-base/js-delta-crdts/issues/47 and try to figure out , if I could use the js implementation to build a proof of concept on top of it.

The benefit would be, the developer does not have to write all the code for the classes. The model is defined and can be used in the code. I know, yjs already hides the most part from the dev and make it really simple to use CRDTS. For a client which does not uses JavaScript, yjs needs to be ported (for example dart for Flutter)

The ultimate goal would be turning something like this

model Person {
    string name;
    int age;
    nested type address {
         string street;
         string house_num;  
         string country;
    };
    array fav_books[];
    map collection;
}

into something like this, which uses CRDTs under the hood.

class Person {
 // props
  // name: string;
  // age: number;
  // address: Address;
  // fav_books: string[];
  // collection: Map<String, any>;

  _props: CrdtMap; // for model props
  _arr: CrdtArray; // for fav_books

  Person() {
    // setup CRDTS etc
  }

  get name(): String {
    return this._props.internal.get("name");
  }

  set name(_name: String) {
    this._props.internal.set("name", _name);
  }

  public get age(): number {
    return this._props.internal.get("age");
  }
  public set age(value: number) {
    this._props.internal.set("age", value);
  }

  public get fav_books(): string[] {
    return this._arr.value();
  }
  /// ... other getter setter

  subscribe(onDelta: Function) {
    this._props.subscribe(onDelta);
    this._arr.subscribe(onDelta);
  }
  apply(delta) {
    // merge logic
  }
}

class Address {
  street: string;
  house_num: string;
  country: string;
}

interface CrdtMap {
  id: string;
  internal: Map<String, any>;
  subscribe(deltas: any);
}

interface CrdtArray {
  value(): [];
  push(val): [];
  subscribe(deltas: any);
  // ...
}

since you have a lot of experience and yjs works pretty good and fast,
what would you suggest, to make a Proof of concept.

While i was using yjs, i wonder how do you actually apply the deltas and the doc object to reach an abitrary nested map or array.