From 7bf6db7398ef49e80ebf1f9b84323aa69c8546c5 Mon Sep 17 00:00:00 2001 From: Zixuan Chen Date: Mon, 4 Nov 2024 17:03:24 +0800 Subject: [PATCH] feat: add push/push_container to LoroText/LoroList/LoroMovableList (#534) * feat: add push_container and push_str to list/text * chore: add changeset file --- .changeset/hip-pears-accept.md | 5 +++++ crates/loro-internal/src/handler.rs | 12 ++++++++++++ crates/loro-wasm/src/lib.rs | 25 +++++++++++++++++++++++++ crates/loro-wasm/tests/basic.test.ts | 21 +++++++++++++++++++++ crates/loro/src/lib.rs | 5 +++++ 5 files changed, 68 insertions(+) create mode 100644 .changeset/hip-pears-accept.md diff --git a/.changeset/hip-pears-accept.md b/.changeset/hip-pears-accept.md new file mode 100644 index 00000000..3f36d6e3 --- /dev/null +++ b/.changeset/hip-pears-accept.md @@ -0,0 +1,5 @@ +--- +"loro-crdt": patch +--- + +Add `push` to LoroText and `pushContainer` to LoroList LoroMovableList diff --git a/crates/loro-internal/src/handler.rs b/crates/loro-internal/src/handler.rs index e44dda79..9c0e2b0f 100644 --- a/crates/loro-internal/src/handler.rs +++ b/crates/loro-internal/src/handler.rs @@ -2270,6 +2270,10 @@ impl TextHandler { MaybeDetached::Attached(a) => a.is_deleted(), } } + + pub fn push_str(&self, s: &str) -> LoroResult<()> { + self.insert_utf8(self.len_utf8(), s) + } } fn event_len(s: &str) -> usize { @@ -2388,6 +2392,10 @@ impl ListHandler { } } + pub fn push_container(&self, child: H) -> LoroResult { + self.insert_container(self.len(), child) + } + pub fn insert_container_with_txn( &self, txn: &mut Transaction, @@ -2925,6 +2933,10 @@ impl MovableListHandler { } } + pub fn push_container(&self, child: H) -> LoroResult { + self.insert_container(self.len(), child) + } + pub fn insert_container_with_txn( &self, txn: &mut Transaction, diff --git a/crates/loro-wasm/src/lib.rs b/crates/loro-wasm/src/lib.rs index f510cfd1..cad63ef8 100644 --- a/crates/loro-wasm/src/lib.rs +++ b/crates/loro-wasm/src/lib.rs @@ -2163,6 +2163,12 @@ impl LoroText { .get_cursor(pos, side_value) .map(|pos| Cursor { pos }) } + + /// Push a string to the end of the text. + pub fn push(&mut self, s: &str) -> JsResult<()> { + self.handler.push_str(s)?; + Ok(()) + } } impl Default for LoroText { @@ -2676,6 +2682,11 @@ impl LoroList { Ok(handler_to_js_value(c, self.doc.clone()).into()) } + #[wasm_bindgen(js_name = "pushContainer", skip_typescript)] + pub fn push_container(&mut self, child: JsContainer) -> JsResult { + self.insert_container(self.length(), child) + } + /// Subscribe to the changes of the list. /// /// Returns a subscription callback, which can be used to unsubscribe. @@ -2997,6 +3008,12 @@ impl LoroMovableList { Ok(handler_to_js_value(c, self.doc.clone()).into()) } + /// Push a container to the end of the list. + #[wasm_bindgen(js_name = "pushContainer", skip_typescript)] + pub fn push_container(&mut self, child: JsContainer) -> JsResult { + self.insert_container(self.length(), child) + } + /// Subscribe to the changes of the list. /// /// Returns a subscription callback, which can be used to unsubscribe. @@ -5129,6 +5146,10 @@ interface LoroList { * ``` */ insertContainer(pos: number, child: C): T extends C ? T : C; + /** + * Push a container to the end of the list. + */ + pushContainer(child: C): T extends C ? T : C; /** * Get the value at the index. If the value is a container, the corresponding handler will be returned. * @@ -5201,6 +5222,10 @@ interface LoroMovableList { * ``` */ insertContainer(pos: number, child: C): T extends C ? T : C; + /** + * Push a container to the end of the list. + */ + pushContainer(child: C): T extends C ? T : C; /** * Get the value at the index. If the value is a container, the corresponding handler will be returned. * diff --git a/crates/loro-wasm/tests/basic.test.ts b/crates/loro-wasm/tests/basic.test.ts index 52c0a993..f5587f56 100644 --- a/crates/loro-wasm/tests/basic.test.ts +++ b/crates/loro-wasm/tests/basic.test.ts @@ -654,3 +654,24 @@ it("json path", () => { expect(result.length).toBe(1); expect(result).toStrictEqual(["1984"]) }) + +it("can push string to text", () => { + const doc = new LoroDoc(); + const text = doc.getText("text"); + text.push("123"); + expect(text.toString()).toBe("123"); +}) + +it("can push container to list", () => { + const doc = new LoroDoc(); + const list = doc.getList("list"); + const map = list.pushContainer(new LoroMap()); + expect(list.toJSON()).toStrictEqual([{}]); +}) + +it("can push container to movable list", () => { + const doc = new LoroDoc(); + const list = doc.getMovableList("list"); + const map = list.pushContainer(new LoroMap()); + expect(list.toJSON()).toStrictEqual([{}]); +}) diff --git a/crates/loro/src/lib.rs b/crates/loro/src/lib.rs index 96f10713..b856babc 100644 --- a/crates/loro/src/lib.rs +++ b/crates/loro/src/lib.rs @@ -1566,6 +1566,11 @@ impl LoroText { pub fn is_deleted(&self) -> bool { self.handler.is_deleted() } + + /// Push a string to the end of the text container. + pub fn push_str(&self, s: &str) -> LoroResult<()> { + self.handler.push_str(s) + } } impl Default for LoroText {