y-crdt / ydotnet

.NET bindings for yrs.
MIT License
35 stars 8 forks source link

Create the Transaction bindings #6

Closed LSViana closed 1 year ago

LSViana commented 1 year ago

Implement the bindings for the Transaction struct based on the exposed bindings.

For each bound method, the implementation and unit tests must be written.

LSViana commented 1 year ago

Hi, @Horusiath!

I finished the Doc bindings and figured out the issues I was having when running multiple unit tests and also with struct parsing on Windows. Then, I started working on the Transaction bindings (this issue).

It went smoothly until the last methods I had to bind: EncodeStateFromSnapshot* (both V1 and V2). The issue I'm having is probably due to misuse of the function, then I'd like to confirm it with you.

No need to run the code/test locally, but can you check if this test makes sense? I'm asking this because when I'm running it, I'm expecting the new document to have the same state as the origin but it's actually missing a letter:

This happens on both macOS and Windows.

I didn't find any resources explaining this but if they exist, please just share the directions and I'll check them.

LSViana commented 1 year ago

Hey, @Horusiath!

An update on the question I mentioned in the comment above: it happens on the Rust side too.

Check this code snippet. ```rust #[test] fn encode_state_from_snapshot_v1() { unsafe { let mut options = Options::default(); options.skip_gc = true; let origin_doc = ydoc_new_with_options(options.clone().into()); let origin_text = ytext(origin_doc, CString::new("name").unwrap().as_ptr()); let origin_write_transaction = ydoc_write_transaction(origin_doc, 0, null()); ytext_insert(origin_text, origin_write_transaction, 0, CString::new("Lucas").unwrap().as_ptr(), null()); ytransaction_commit(origin_write_transaction); let origin_read_transaction = ydoc_read_transaction(origin_doc); let mut snapshot_length = 0; let snapshot = ytransaction_snapshot(origin_read_transaction, &mut snapshot_length); let mut state_diff_length = 0; let state_diff = ytransaction_encode_state_from_snapshot_v1(origin_read_transaction, snapshot, snapshot_length, &mut state_diff_length); let target_doc = ydoc_new_with_options(options.clone().into()); let target_text = ytext(target_doc, CString::new("name").unwrap().as_ptr()); let target_write_transaction = ydoc_write_transaction(target_doc, 0, null()); ytransaction_apply(target_write_transaction, state_diff, state_diff_length); let target_text_string = CString::from_raw(ytext_string(target_text, target_write_transaction)); let target_text_string = target_text_string.to_str().unwrap(); assert_eq!("Lucas", target_text_string); } } ```

It's a unit test that can be pasted at the bottom of yffi/src/lib.rs.

The results are the same I got on the C# side: image

So, in short, I'm probably misusing the library here and I'll need some extra instruction to understand this feature correctly.

Horusiath commented 1 year ago

Thanks, I'll take a look at it.