Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support nested CRDT structures #21

Open
heckj opened this issue Feb 20, 2023 · 7 comments
Open

Support nested CRDT structures #21

heckj opened this issue Feb 20, 2023 · 7 comments

Comments

@heckj
Copy link
Collaborator

heckj commented Feb 20, 2023

Somewhere down the road, we'll want to support nested CRDT data structures. For example, allowing and supporting a YArray of YText, where the order within the array is managed by the CRDTs, and updates within each text inside the array is also managed by the CRDT. This is supported today in Yjs, and Bartosz built the same support for the WASM language bindings.

Taking a snapshot of the details he shared within Discord of how he tackled this scenario:

the general idea in the WebAssembly example:

  1. Have an inner enum that's representing an either prelim or integrated state of the y-type.
  2. y-type wrapping structure that's works like struct YText(RefCell<MyEnum<String, yrs::TextRef>>) - ref cell is useful here because it has replace method.
  3. implement Prelim trait for that structure - the integrate method is executed after the block has been created, and it can be used to append prelim content values and finally to swap the prelim implementation with the integrated one.

The WASM code has these examples:

The "insert" logic, stashing a preliminary type marker within an embedded enum:

The replacement logic, converting preliminary types to final types:

@nugmanoff
Copy link
Contributor

Let me add links to what @Waidhoferj has done as part of his work on ypy:

Have an inner enum that's representing an either prelim or integrated state of the y-type.

Here is essentially the same thing in ypy:

The rest of the logic (basically just the other methods like insert, move_to & etc) can be found in YArray implementation:

@fivestones
Copy link

Do you think this will ever have progress here or is there some other way to do this in swift today?

@heckj
Copy link
Collaborator Author

heckj commented Oct 9, 2023

hey @fivestones - it's definitely possible, but we haven't (as you can likely see) made any coding progress on this project in a few months. It's doable, but we're light on development time on the Rust side to make this happen. I can't make any promises of when it will be completed currently, as there's no active movement on the Rust side of this.

@nugmanoff
Copy link
Contributor

@fivestones thanks for reaching out! seconding @heckj here, it definitely is possible to do it in this library, you would need to do some amount of Rust though. Reference links that I've attached above still apply. Unfortunately personally I have been quite tight on time lately, so I can't give any hard estimates, but plan is there.

Let me know if you want to try do it – I will do my best to assist you.

@fivestones
Copy link

Thanks both of you for responding. I'd love to see this more fleshed out but I can also see you guys have been busy. I also see you @heckj have been making a lot of progress with automerge in swift. I've been looking into seeing how I might make use of that. I would dive in here maybe except that I'd have to learn some rust first 😄 (which I guess isn't out of the question but then I'm in the same state as you guys--busy).
Thanks for all you've already done!

@nugmanoff
Copy link
Contributor

I didn't know Rust at all (nor do I know it enough now) when I decided to take a stab at implementing POC for this whole thing. It is not that much Rust really, just a simple wrapping code here and there. Mostly it is about wrapping your head around all of the moving parts (yrs itself, UniFFI bindgen, Rust wrapping code, safely interfacing with generated bindings from Swift & etc).

@ghost
Copy link

ghost commented Dec 28, 2023

@fivestones one potential workaround is to set up a YArray<String> of IDs, and then separately maintain root-level YTexts (or other shared types) named with those IDs.

I'm not sure if there are any significant downsides that I'm missing, but it seems to be working for a prototype I'm building at the moment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants