From e9e2328f03b845c9df1d61e67e91bbe0e551d904 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Tue, 1 Apr 2025 20:10:03 +0100 Subject: [PATCH] Expose merge_text_with_cursors on API --- backend/reconcile/src/lib.rs | 8 +++-- backend/sync_lib/src/lib.rs | 18 ++++++++++- backend/sync_lib/tests/web.rs | 58 +++++++++++++++++++++++++++++++++-- 3 files changed, 79 insertions(+), 5 deletions(-) diff --git a/backend/reconcile/src/lib.rs b/backend/reconcile/src/lib.rs index 9c5bb764..8023cc15 100644 --- a/backend/reconcile/src/lib.rs +++ b/backend/reconcile/src/lib.rs @@ -1,7 +1,11 @@ +mod cursor; mod diffs; mod operation_transformation; mod tokenizer; mod utils; -pub use operation_transformation::{EditedText, reconcile, reconcile_with_tokenizer}; -pub use tokenizer::token::Token; +pub use cursor::{CursorPosition, TextWithCursors}; +pub use operation_transformation::{ + EditedText, reconcile, reconcile_with_cursors, reconcile_with_tokenizer, +}; +pub use tokenizer::{Tokenizer, token::Token}; diff --git a/backend/sync_lib/src/lib.rs b/backend/sync_lib/src/lib.rs index 6f27e055..dc35e27f 100644 --- a/backend/sync_lib/src/lib.rs +++ b/backend/sync_lib/src/lib.rs @@ -8,12 +8,15 @@ //! # Modules //! //! - `errors`: Contains error types used in this crate. + use core::str; use base64::{Engine as _, engine::general_purpose::STANDARD}; +use cursor::OwnedTextWithCursors; use errors::SyncLibError; use wasm_bindgen::prelude::*; +pub mod cursor; pub mod errors; /// Encode binary data for easy transport over HTTP. Inverse of @@ -93,7 +96,7 @@ pub fn merge(parent: &[u8], left: &[u8], right: &[u8]) -> Vec { } } -/// WASM wrapper around `reconcile::reconcile` for text merging. +/// WASM wrapper around `reconcile::reconcile` for merging text. #[wasm_bindgen(js_name = mergeText)] #[must_use] pub fn merge_text(parent: &str, left: &str, right: &str) -> String { @@ -102,6 +105,19 @@ pub fn merge_text(parent: &str, left: &str, right: &str) -> String { reconcile::reconcile(parent, left, right) } +/// WASM wrapper around `reconcile::reconcile_with_cursors` for merging text. +#[wasm_bindgen(js_name = mergeText)] +#[must_use] +pub fn merge_text_with_cursors( + parent: &str, + left: OwnedTextWithCursors, + right: OwnedTextWithCursors, +) -> OwnedTextWithCursors { + set_panic_hook(); + + reconcile::reconcile_with_cursors(parent, left.into(), right.into()).into() +} + /// Heuristically determine if the given data is a binary or a text file's /// content. #[wasm_bindgen(js_name = isBinary)] diff --git a/backend/sync_lib/tests/web.rs b/backend/sync_lib/tests/web.rs index e45cbea6..017e2dc2 100644 --- a/backend/sync_lib/tests/web.rs +++ b/backend/sync_lib/tests/web.rs @@ -1,5 +1,8 @@ use insta::assert_debug_snapshot; -use sync_lib::*; +use sync_lib::{ + cursor::{OwnedCursorPosition, OwnedTextWithCursors}, + *, +}; use wasm_bindgen_test::*; #[wasm_bindgen_test(unsupported = test)] @@ -23,11 +26,62 @@ fn test_base64_to_bytes_error() { } #[wasm_bindgen_test(unsupported = test)] -fn merge_text() { +fn test_merge() { let left = b"hello "; let right = b"world"; let result = merge(b"", left, right); assert_eq!(result, b"hello world"); + + let left = b"\0binary"; + let right = b"other"; + let result = merge(b"", left, right); + assert_eq!(result, right); +} + +#[wasm_bindgen_test(unsupported = test)] +fn test_merge_text() { + let left = "hello "; + let right = "world"; + let result = merge_text("", left, right); + assert_eq!(result, "hello world"); +} + +#[wasm_bindgen_test(unsupported = test)] +fn test_merge_text_with_cursors() { + let result = merge_text_with_cursors( + "hi", + OwnedTextWithCursors::new("hi world", vec![]), + OwnedTextWithCursors::new( + "hi", + vec![ + OwnedCursorPosition { + id: 0, + char_index: 1, + }, + OwnedCursorPosition { + id: 1, + char_index: 2, + }, + ], + ), + ); + + assert_eq!( + result, + OwnedTextWithCursors::new( + "hi world", + vec![ + OwnedCursorPosition { + id: 0, + char_index: 1, + }, + OwnedCursorPosition { + id: 1, + char_index: 8, + } + ] + ), + ); } #[wasm_bindgen_test(unsupported = test)]