diff --git a/y-octo-node/index.d.ts b/y-octo-node/index.d.ts index 685a85f..10a5a16 100644 --- a/y-octo-node/index.d.ts +++ b/y-octo-node/index.d.ts @@ -23,8 +23,8 @@ export class Doc { createArray(): YArray createText(): YText createMap(): YMap - applyUpdate(update: Buffer): Buffer - encodeUpdateV1(): Buffer + applyUpdate(update: Buffer): void + encodeStateAsUpdateV1(state?: Buffer | undefined | null): Buffer gc(): void onUpdate(callback: (result: Uint8Array) => void): void } diff --git a/y-octo-node/src/doc.rs b/y-octo-node/src/doc.rs index 3b9b641..e37ab80 100644 --- a/y-octo-node/src/doc.rs +++ b/y-octo-node/src/doc.rs @@ -2,7 +2,7 @@ use napi::{ bindgen_prelude::{Buffer as JsBuffer, JsFunction}, threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode}, }; -use y_octo::{Doc as YDoc, History}; +use y_octo::{CrdtRead, Doc as YDoc, History, RawDecoder, StateVector}; use super::*; @@ -85,19 +85,24 @@ impl Doc { } #[napi] - pub fn apply_update(&mut self, update: JsBuffer) -> Result { - self.doc - .apply_update_from_binary_v1(update) - .and_then(|u| u.encode_v1().map(|v| v.into())) - .map_err(anyhow::Error::from) + pub fn apply_update(&mut self, update: JsBuffer) -> Result<()> { + self.doc.apply_update_from_binary_v1(update)?; + + Ok(()) } #[napi] - pub fn encode_update_v1(&self) -> Result { - self.doc - .encode_update_v1() - .map(|v| v.into()) - .map_err(anyhow::Error::from) + pub fn encode_state_as_update_v1(&self, state: Option) -> Result { + let result = match state { + Some(state) => { + let mut decoder = RawDecoder::new(state.as_ref()); + let state = StateVector::read(&mut decoder)?; + self.doc.encode_state_as_update_v1(&state) + } + None => self.doc.encode_update_v1(), + }; + + result.map(|v| v.into()).map_err(anyhow::Error::from) } #[napi] diff --git a/y-octo-node/tests/doc.spec.mts b/y-octo-node/tests/doc.spec.mts index 800cf28..d854746 100644 --- a/y-octo-node/tests/doc.spec.mts +++ b/y-octo-node/tests/doc.spec.mts @@ -40,7 +40,7 @@ test("doc test", { concurrency: false }, async (t) => { text.insert(2, "c"); let doc2 = new Doc(client_id); - doc2.applyUpdate(doc.encodeUpdateV1()); + doc2.applyUpdate(doc.encodeStateAsUpdateV1()); let array2 = doc2.getOrCreateArray("array"); let map2 = doc2.getOrCreateMap("map"); diff --git a/y-octo-node/tests/map.spec.mts b/y-octo-node/tests/map.spec.mts index 0095473..f499766 100644 --- a/y-octo-node/tests/map.spec.mts +++ b/y-octo-node/tests/map.spec.mts @@ -84,7 +84,7 @@ test("map test", { concurrency: false }, async (t) => { sub_text.insert(2, "c"); let doc2 = new Y.Doc(); - Y.applyUpdate(doc2, doc.encodeUpdateV1()); + Y.applyUpdate(doc2, doc.encodeStateAsUpdateV1()); let map2 = doc2.getMap("map"); let sub_array2 = map2.get("array") as Y.Array; diff --git a/y-octo/src/doc/document.rs b/y-octo/src/doc/document.rs index 148d86e..a180ffc 100644 --- a/y-octo/src/doc/document.rs +++ b/y-octo/src/doc/document.rs @@ -220,16 +220,15 @@ impl Doc { Ok(doc) } - pub fn apply_update_from_binary_v1>(&mut self, binary: T) -> JwstCodecResult { + pub fn apply_update_from_binary_v1>(&mut self, binary: T) -> JwstCodecResult { let mut decoder = RawDecoder::new(binary.as_ref()); let update = Update::read(&mut decoder)?; self.apply_update(update) } - pub fn apply_update(&mut self, mut update: Update) -> JwstCodecResult { + pub fn apply_update(&mut self, mut update: Update) -> JwstCodecResult { let mut store = self.store.write().unwrap(); let mut retry = false; - let before_state = store.get_state_vector(); loop { for (mut s, offset) in update.iter(store.get_state_vector()) { if let Node::Item(item) = &mut s { @@ -288,7 +287,7 @@ impl Doc { } } - store.diff_state_vector(&before_state, false) + Ok(()) } pub fn keys(&self) -> Vec { diff --git a/y-octo/src/doc/store.rs b/y-octo/src/doc/store.rs index cb5ac95..cea9364 100644 --- a/y-octo/src/doc/store.rs +++ b/y-octo/src/doc/store.rs @@ -780,7 +780,6 @@ impl DocStore { let first_block = items.get(index).unwrap(); let offset = first_block.clock() - clock; if offset != 0 { - // needs to implement Content split first vec_struct_info.push_back(first_block.clone().split_at(offset)?.1); } else { vec_struct_info.push_back(first_block.clone()); @@ -800,17 +799,10 @@ impl DocStore { let mut delete_set = DeleteSet::default(); for (client, nodes) in refs { - let ranges = nodes + nodes .iter() .filter(|n| n.deleted()) - .map(|n| { - let clock = n.id().clock; - clock..clock + n.len() - }) - .collect::>(); - if !ranges.is_empty() { - delete_set.batch_add_ranges(*client, ranges); - } + .for_each(|n| delete_set.add(*client, n.clock(), n.len())); } delete_set