diff --git a/Cargo.lock b/Cargo.lock index baaef2d5..41048006 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -703,9 +703,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -956,9 +956,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "lock_api" diff --git a/crates/loro-internal/Cargo.toml b/crates/loro-internal/Cargo.toml index 180c592e..3db93322 100644 --- a/crates/loro-internal/Cargo.toml +++ b/crates/loro-internal/Cargo.toml @@ -41,7 +41,7 @@ itertools = { workspace = true } enum_dispatch = { workspace = true } im = { version = "15.1.0", features = ["serde"] } generic-btree = { version = "^0.10.5" } -getrandom = "0.2.10" +getrandom = "0.2.15" once_cell = "1.18.0" leb128 = "0.2.5" num-traits = "0.2" diff --git a/crates/loro-internal/fuzz/Cargo.toml b/crates/loro-internal/fuzz/Cargo.toml index 7b9d9b17..a79c07f8 100644 --- a/crates/loro-internal/fuzz/Cargo.toml +++ b/crates/loro-internal/fuzz/Cargo.toml @@ -19,48 +19,8 @@ features = ["test_utils"] [workspace] members = ["."] -[[bin]] -name = "yata" -path = "fuzz_targets/yata.rs" -test = false -doc = false - -# [profile.dev] -# lto = true -# opt-level = 3 - -[[bin]] -name = "text_refactored" -path = "fuzz_targets/text_refactored.rs" -test = false -doc = false - -[[bin]] -name = "recursive_refactored" -path = "fuzz_targets/recursive_refactored.rs" -test = false -doc = false - [[bin]] name = "import" path = "fuzz_targets/import.rs" test = false doc = false - -[[bin]] -name = "tree" -path = "fuzz_targets/tree.rs" -test = false -doc = false - -[[bin]] -name = "richtext" -path = "fuzz_targets/richtext.rs" -test = false -doc = false - -[[bin]] -name = "map" -path = "fuzz_targets/map.rs" -test = false -doc = false diff --git a/crates/loro-internal/fuzz/fuzz_targets/map.rs b/crates/loro-internal/fuzz/fuzz_targets/map.rs deleted file mode 100644 index 1841a6d2..00000000 --- a/crates/loro-internal/fuzz/fuzz_targets/map.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![no_main] - -use libfuzzer_sys::fuzz_target; -use loro_internal::fuzz::crdt_fuzzer::{test_multi_sites, Action, FuzzTarget}; - -fuzz_target!(|actions: Vec| { - test_multi_sites(5, vec![FuzzTarget::Map], &mut actions.clone()) -}); diff --git a/crates/loro-internal/fuzz/fuzz_targets/recursive_refactored.rs b/crates/loro-internal/fuzz/fuzz_targets/recursive_refactored.rs deleted file mode 100644 index 564da7b3..00000000 --- a/crates/loro-internal/fuzz/fuzz_targets/recursive_refactored.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![no_main] -use libfuzzer_sys::fuzz_target; -use loro_internal::fuzz::recursive_refactored::{test_multi_sites, Action}; - -fuzz_target!(|actions: Vec| { test_multi_sites(5, &mut actions.clone()) }); diff --git a/crates/loro-internal/fuzz/fuzz_targets/richtext.rs b/crates/loro-internal/fuzz/fuzz_targets/richtext.rs deleted file mode 100644 index ae6b2398..00000000 --- a/crates/loro-internal/fuzz/fuzz_targets/richtext.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![no_main] -use libfuzzer_sys::fuzz_target; -use loro_internal::fuzz::richtext::{test_multi_sites, Action}; - -fuzz_target!(|actions: Vec| { test_multi_sites(5, &mut actions.clone()) }); diff --git a/crates/loro-internal/fuzz/fuzz_targets/text_refactored.rs b/crates/loro-internal/fuzz/fuzz_targets/text_refactored.rs deleted file mode 100644 index f6714169..00000000 --- a/crates/loro-internal/fuzz/fuzz_targets/text_refactored.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![no_main] -use libfuzzer_sys::fuzz_target; -use loro_internal::fuzz::{test_multi_sites, Action}; - -fuzz_target!(|actions: Vec| { test_multi_sites(5, &mut actions.clone()) }); diff --git a/crates/loro-internal/fuzz/fuzz_targets/tree.rs b/crates/loro-internal/fuzz/fuzz_targets/tree.rs deleted file mode 100644 index 4a393c22..00000000 --- a/crates/loro-internal/fuzz/fuzz_targets/tree.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![no_main] -use libfuzzer_sys::fuzz_target; -use loro_internal::fuzz::tree::{test_multi_sites, Action}; - -fuzz_target!(|actions: Vec| { test_multi_sites(5, &mut actions.clone()) }); diff --git a/crates/loro-internal/src/loro.rs b/crates/loro-internal/src/loro.rs index 9fc153fd..59d47264 100644 --- a/crates/loro-internal/src/loro.rs +++ b/crates/loro-internal/src/loro.rs @@ -212,7 +212,12 @@ impl LoroDoc { /// Is the document empty? (no ops) #[inline(always)] pub fn can_reset_with_snapshot(&self) -> bool { - self.oplog.lock().unwrap().is_empty() && self.state.lock().unwrap().is_empty() + let oplog = self.oplog.lock().unwrap(); + if oplog.batch_importing { + return false; + } + + oplog.is_empty() && self.state.lock().unwrap().is_empty() } /// Whether [OpLog] and [DocState] are detached. @@ -1280,7 +1285,10 @@ impl LoroDoc { .id_to_idx(&pos.container) .ok_or(CannotFindRelativePosition::ContainerDeleted)?; // We know where the target id is when we trace back to the delete_op_id. - let delete_op_id = find_last_delete_op(&oplog, id, idx).unwrap(); + let Some(delete_op_id) = find_last_delete_op(&oplog, id, idx) else { + tracing::error!("Cannot find id {}", id); + return Err(CannotFindRelativePosition::IdNotFound); + }; // Should use persist mode so that it will force all the diff calculators to use the `checkout` mode let mut diff_calc = DiffCalculator::new(true); let before_frontiers: Frontiers = oplog.dag.find_deps_of_id(delete_op_id); @@ -1443,7 +1451,7 @@ impl LoroDoc { } fn find_last_delete_op(oplog: &OpLog, id: ID, idx: ContainerIdx) -> Option { - let start_vv = oplog.dag.frontiers_to_vv(&id.into()).unwrap(); + let start_vv = oplog.dag.frontiers_to_vv(&id.into())?; for change in oplog.iter_changes_causally_rev(&start_vv, oplog.vv()) { for op in change.ops.iter().rev() { if op.container != idx { diff --git a/crates/loro-wasm/CHANGELOG.md b/crates/loro-wasm/CHANGELOG.md index e7c766dc..aa9f327c 100644 --- a/crates/loro-wasm/CHANGELOG.md +++ b/crates/loro-wasm/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## 0.16.10 + +### Patch Changes + +- 7cf54e8: Fix batch importing with snapshot + +## 0.16.9 + +### Patch Changes + +- a761430: Fix build script + +## 0.16.8 + +### Patch Changes + +- 38b4bcf: Add text update API + + - Remove the patch for crypto + - Add text update API (#404) + - Check invalid root container name (#411) + + ### 🐛 Bug Fixes + + - Workaround lldb bug make loro crate debuggable (#414) + - Delete the **bring back** tree node from the undo container remap (#423) + + ### 📚 Documentation + + - Fix typo + - Refine docs about event (#417) + + ### 🎨 Styling + + - Use clippy to perf code (#407) + + ### ⚙️ Miscellaneous Tasks + + - Add test tools (#410) + ## 0.16.7 ### Patch Changes diff --git a/crates/loro-wasm/Cargo.toml b/crates/loro-wasm/Cargo.toml index e5860907..397e8e1d 100644 --- a/crates/loro-wasm/Cargo.toml +++ b/crates/loro-wasm/Cargo.toml @@ -15,7 +15,7 @@ wasm-bindgen = "=0.2.92" serde-wasm-bindgen = { version = "^0.6.5" } wasm-bindgen-derive = "0.2.1" console_error_panic_hook = { version = "0.1.6", optional = true } -getrandom = { version = "0.2.10", features = ["js"] } +getrandom = { version = "0.2.15", features = ["js"] } serde = { workspace = true } rle = { path = "../rle", package = "loro-rle" } tracing-wasm = "0.2.1" diff --git a/crates/loro-wasm/package.json b/crates/loro-wasm/package.json index 5579f4f9..23a11301 100644 --- a/crates/loro-wasm/package.json +++ b/crates/loro-wasm/package.json @@ -1,6 +1,6 @@ { "name": "loro-wasm", - "version": "0.16.7", + "version": "0.16.10", "description": "Loro CRDTs is a high-performance CRDT framework that makes your app state synchronized, collaborative and maintainable effortlessly.", "keywords": [ "crdt", diff --git a/crates/loro-wasm/scripts/nodejs_patch.js b/crates/loro-wasm/scripts/nodejs_patch.js index ad65e8fb..d237e63f 100644 --- a/crates/loro-wasm/scripts/nodejs_patch.js +++ b/crates/loro-wasm/scripts/nodejs_patch.js @@ -1,5 +1,11 @@ -const { webcrypto } = require("crypto"); -Object.defineProperty(globalThis, 'crypto', { - value: webcrypto, - writable: true -}); \ No newline at end of file +// Don't patch this if it already exists (for example in Deno) +if (!globalThis.crypto) { + // We need this patch because we use `getrandom` crate in Rust, which relies on this patch + // for nodejs + // https://docs.rs/getrandom/latest/getrandom/#nodejs-es-module-support + const { webcrypto } = require("crypto"); + Object.defineProperty(globalThis, 'crypto', { + value: webcrypto, + writable: true + }); +} diff --git a/crates/loro-wasm/src/lib.rs b/crates/loro-wasm/src/lib.rs index e2e7fc53..3238cd56 100644 --- a/crates/loro-wasm/src/lib.rs +++ b/crates/loro-wasm/src/lib.rs @@ -1561,7 +1561,7 @@ impl LoroText { /// text.insert(0, "Hello"); /// text.update("Hello World"); /// ``` - pub fn update(&self, text: &str) -> () { + pub fn update(&self, text: &str) { self.handler.update(text); } diff --git a/crates/loro/src/lib.rs b/crates/loro/src/lib.rs index f59cba9b..318c598a 100644 --- a/crates/loro/src/lib.rs +++ b/crates/loro/src/lib.rs @@ -247,7 +247,7 @@ impl LoroDoc { /// /// The data can be in arbitrary order. The import result will be the same. #[inline] - pub fn import_batch(&mut self, bytes: &[Vec]) -> LoroResult<()> { + pub fn import_batch(&self, bytes: &[Vec]) -> LoroResult<()> { self.doc.import_batch(bytes) } diff --git a/crates/loro/tests/issue.rs b/crates/loro/tests/issue.rs new file mode 100644 index 00000000..60caa920 --- /dev/null +++ b/crates/loro/tests/issue.rs @@ -0,0 +1,14 @@ +use loro::LoroDoc; + +#[ctor::ctor] +fn init() { + dev_utils::setup_test_log(); +} + +#[test] +fn issue_0() { + let bytes = include_bytes!("./issue_0.bin"); + let doc = LoroDoc::new(); + doc.import_batch(&[bytes.into()]).unwrap(); + doc.export_snapshot(); +} diff --git a/crates/loro/tests/issue_0.bin b/crates/loro/tests/issue_0.bin new file mode 100644 index 00000000..ec909349 Binary files /dev/null and b/crates/loro/tests/issue_0.bin differ diff --git a/loro-js/CHANGELOG.md b/loro-js/CHANGELOG.md index 04882384..1fd2c8ef 100644 --- a/loro-js/CHANGELOG.md +++ b/loro-js/CHANGELOG.md @@ -1,5 +1,52 @@ # Changelog +## 0.16.10 + +### Patch Changes + +- 7cf54e8: Fix batch importing with snapshot +- Updated dependencies [7cf54e8] + - loro-wasm@0.16.10 + +## 0.16.9 + +### Patch Changes + +- a761430: Fix build script +- Updated dependencies [a761430] + - loro-wasm@0.16.9 + +## 0.16.8 + +### Patch Changes + +- 38b4bcf: Add text update API + + - Remove the patch for crypto + - Add text update API (#404) + - Check invalid root container name (#411) + + ### 🐛 Bug Fixes + + - Workaround lldb bug make loro crate debuggable (#414) + - Delete the **bring back** tree node from the undo container remap (#423) + + ### 📚 Documentation + + - Fix typo + - Refine docs about event (#417) + + ### 🎨 Styling + + - Use clippy to perf code (#407) + + ### ⚙️ Miscellaneous Tasks + + - Add test tools (#410) + +- Updated dependencies [38b4bcf] + - loro-wasm@0.16.8 + ## 0.16.7 ### Patch Changes diff --git a/loro-js/package.json b/loro-js/package.json index cedc187d..7dcf8cb9 100644 --- a/loro-js/package.json +++ b/loro-js/package.json @@ -1,6 +1,6 @@ { "name": "loro-crdt", - "version": "0.16.7", + "version": "0.16.10", "description": "Loro CRDTs is a high-performance CRDT framework that makes your app state synchronized, collaborative and maintainable effortlessly.", "keywords": [ "crdt",