peer-base / js-delta-crdts

Delta State-based CRDTs in Javascript
192 stars 16 forks source link

Nested Types #47

Closed Manuelbaun closed 3 years ago

Manuelbaun commented 4 years ago

Hi @pgte , for a Uni project, I am researching the possibility of modeling a schema, like the own presented below, and generating CRDTs, to sync clients. Somehow building a middleware, enable the client to work offline. The ultimate goal is, defining a schema and generating the code for ts/js, dart, c# etc, like gRPC does, to have a custom sync protocol for your application. For the model language, I got inspired by the Primsa schema and gRPC.

Pseudocode:

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

Then a generated TypeScript/JavaScript class could look like this in a very naive first draft:

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);
  // ...
}

My question is, how would you use your existing CRDTs to model it? And how would you get the deltas and apply the deltas, if you would do it manually?

Kind regards