yrs/
doc.rs

1use crate::block::{ClientID, ItemContent, ItemPtr, Prelim};
2use crate::branch::BranchPtr;
3use crate::encoding::read::Error;
4use crate::event::{SubdocsEvent, TransactionCleanupEvent, UpdateEvent};
5use crate::store::{DocStore, StoreInner};
6use crate::transaction::{Origin, Transaction, TransactionMut};
7use crate::types::{RootRef, ToJson};
8use crate::updates::decoder::{Decode, Decoder};
9use crate::updates::encoder::{Encode, Encoder};
10use crate::utils::OptionExt;
11use crate::{
12    uuid_v4, uuid_v4_from, ArrayRef, BranchID, MapRef, Out, ReadTxn, TextRef, Transact,
13    TransactionAcqError, Uuid, WriteTxn, XmlFragmentRef,
14};
15use crate::{Any, Subscription};
16use std::collections::HashMap;
17use std::convert::TryFrom;
18use std::fmt::Formatter;
19use std::sync::Arc;
20
21/// A Yrs document type. Documents are the most important units of collaborative resources management.
22/// All shared collections live within a scope of their corresponding documents. All updates are
23/// generated on per-document basis (rather than individual shared type). All operations on shared
24/// collections happen via [Transaction], which lifetime is also bound to a document.
25///
26/// Document manages so-called root types, which are top-level shared types definitions (as opposed
27/// to recursively nested types).
28///
29/// # Example
30///
31/// ```rust
32/// use yrs::{Doc, ReadTxn, StateVector, Text, Transact, Update};
33/// use yrs::updates::decoder::Decode;
34/// use yrs::updates::encoder::Encode;
35///
36/// let doc = Doc::new();
37/// let root = doc.get_or_insert_text("root-type-name");
38/// let mut txn = doc.transact_mut(); // all Yrs operations happen in scope of a transaction
39/// root.push(&mut txn, "hello world"); // append text to our collaborative document
40///
41/// // in order to exchange data with other documents we first need to create a state vector
42/// let remote_doc = Doc::new();
43/// let mut remote_txn = remote_doc.transact_mut();
44/// let state_vector = remote_txn.state_vector().encode_v1();
45///
46/// // now compute a differential update based on remote document's state vector
47/// let update = txn.encode_diff_v1(&StateVector::decode_v1(&state_vector).unwrap());
48///
49/// // both update and state vector are serializable, we can pass the over the wire
50/// // now apply update to a remote document
51/// remote_txn.apply_update(Update::decode_v1(update.as_slice()).unwrap());
52/// ```
53#[repr(transparent)]
54#[derive(Debug, Clone)]
55pub struct Doc {
56    pub(crate) store: DocStore,
57}
58
59unsafe impl Send for Doc {}
60unsafe impl Sync for Doc {}
61
62impl TryFrom<Out> for Doc {
63    type Error = Out;
64
65    fn try_from(value: Out) -> Result<Self, Self::Error> {
66        match value {
67            Out::YDoc(value) => Ok(value),
68            other => Err(other),
69        }
70    }
71}
72
73impl Doc {
74    /// Creates a new document with a randomized client identifier.
75    pub fn new() -> Self {
76        Self::with_options(Options::default())
77    }
78
79    #[doc(hidden)]
80    pub fn into_raw(self) -> *const Doc {
81        let ptr = Arc::into_raw(self.store.0);
82        ptr as *const Doc
83    }
84
85    #[doc(hidden)]
86    pub unsafe fn from_raw(ptr: *const Doc) -> Doc {
87        let ptr = ptr as *const StoreInner;
88        let cell = Arc::from_raw(ptr);
89        Doc {
90            store: DocStore(cell),
91        }
92    }
93
94    #[doc(hidden)]
95    pub fn as_raw(self) -> *const Doc {
96        let ptr = Arc::as_ptr(&self.store.0);
97        ptr as *const Doc
98    }
99
100    /// Creates a new document with a specified `client_id`. It's up to a caller to guarantee that
101    /// this identifier is unique across all communicating replicas of that document.
102    pub fn with_client_id(client_id: ClientID) -> Self {
103        Self::with_options(Options::with_client_id(client_id))
104    }
105
106    /// Creates a new document with a configured set of [Options].
107    pub fn with_options(options: Options) -> Self {
108        Doc {
109            store: DocStore::new(options, None),
110        }
111    }
112
113    pub(crate) fn subdoc(parent: ItemPtr, options: Options) -> Self {
114        Doc {
115            store: DocStore::new(options, Some(parent)),
116        }
117    }
118
119    pub(crate) fn store(&self) -> &DocStore {
120        &self.store
121    }
122
123    /// A unique client identifier, that's also a unique identifier of current document replica
124    /// and it's subdocuments.
125    ///
126    /// Default: randomly generated.
127    pub fn client_id(&self) -> ClientID {
128        self.store.options().client_id
129    }
130
131    /// A globally unique identifier, that's also a unique identifier of current document replica,
132    /// and unlike [Doc::client_id] it's not shared with its subdocuments.
133    ///
134    /// Default: randomly generated UUID v4.
135    pub fn guid(&self) -> Uuid {
136        self.store.options().guid.clone()
137    }
138
139    /// Returns a unique collection identifier, if defined.
140    ///
141    /// Default: `None`.
142    pub fn collection_id(&self) -> Option<Arc<str>> {
143        self.store.options().collection_id.clone()
144    }
145
146    /// Informs if current document is skipping garbage collection on deleted collections
147    /// on transaction commit.
148    ///
149    /// Default: `false`.
150    pub fn skip_gc(&self) -> bool {
151        self.store.options().skip_gc
152    }
153
154    /// If current document is subdocument, it will automatically for a document to load.
155    ///
156    /// Default: `false`.
157    pub fn auto_load(&self) -> bool {
158        self.store.options().auto_load
159    }
160
161    /// Whether the document should be synced by the provider now.
162    /// This is toggled to true when you call [Doc::load]
163    ///
164    /// Default value: `true`.
165    pub fn should_load(&self) -> bool {
166        self.store.options().should_load
167    }
168
169    /// Returns encoding used to count offsets and lengths in text operations.
170    pub fn offset_kind(&self) -> OffsetKind {
171        self.store.options().offset_kind
172    }
173
174    /// Returns a [TextRef] data structure stored under a given `name`. Text structures are used for
175    /// collaborative text editing: they expose operations to append and remove chunks of text,
176    /// which are free to execute concurrently by multiple peers over remote boundaries.
177    ///
178    /// If no structure under defined `name` existed before, it will be created and returned
179    /// instead.
180    ///
181    /// If a structure under defined `name` already existed, but its type was different it will be
182    /// reinterpreted as a text (in such case a sequence component of complex data type will be
183    /// interpreted as a list of text chunks).
184    ///
185    /// # Panics
186    ///
187    /// This method requires exclusive access to an underlying document store. If there
188    /// is another transaction in process, it will panic. It's advised to define all root shared
189    /// types during the document creation.
190    pub fn get_or_insert_text<N: Into<Arc<str>>>(&self, name: N) -> TextRef {
191        TextRef::root(name).get_or_create(&mut self.transact_mut())
192    }
193
194    /// Returns a [MapRef] data structure stored under a given `name`. Maps are used to store key-value
195    /// pairs associated. These values can be primitive data (similar but not limited to
196    /// a JavaScript Object Notation) as well as other shared types (Yrs maps, arrays, text
197    /// structures etc.), enabling to construct a complex recursive tree structures.
198    ///
199    /// If no structure under defined `name` existed before, it will be created and returned
200    /// instead.
201    ///
202    /// If a structure under defined `name` already existed, but its type was different it will be
203    /// reinterpreted as a map (in such case a map component of complex data type will be
204    /// interpreted as native map).
205    ///
206    /// # Panics
207    ///
208    /// This method requires exclusive access to an underlying document store. If there
209    /// is another transaction in process, it will panic. It's advised to define all root shared
210    /// types during the document creation.
211    pub fn get_or_insert_map<N: Into<Arc<str>>>(&self, name: N) -> MapRef {
212        MapRef::root(name).get_or_create(&mut self.transact_mut())
213    }
214
215    /// Returns an [ArrayRef] data structure stored under a given `name`. Array structures are used for
216    /// storing a sequences of elements in ordered manner, positioning given element accordingly
217    /// to its index.
218    ///
219    /// If no structure under defined `name` existed before, it will be created and returned
220    /// instead.
221    ///
222    /// If a structure under defined `name` already existed, but its type was different it will be
223    /// reinterpreted as an array (in such case a sequence component of complex data type will be
224    /// interpreted as a list of inserted values).
225    ///
226    /// # Panics
227    ///
228    /// This method requires exclusive access to an underlying document store. If there
229    /// is another transaction in process, it will panic. It's advised to define all root shared
230    /// types during the document creation.
231    pub fn get_or_insert_array<N: Into<Arc<str>>>(&self, name: N) -> ArrayRef {
232        ArrayRef::root(name).get_or_create(&mut self.transact_mut())
233    }
234
235    /// Returns a [XmlFragmentRef] data structure stored under a given `name`. XML elements represent
236    /// nodes of XML document. They can contain attributes (key-value pairs, both of string type)
237    /// and other nested XML elements or text values, which are stored in their insertion
238    /// order.
239    ///
240    /// If no structure under defined `name` existed before, it will be created and returned
241    /// instead.
242    ///
243    /// If a structure under defined `name` already existed, but its type was different it will be
244    /// reinterpreted as a XML element (in such case a map component of complex data type will be
245    /// interpreted as map of its attributes, while a sequence component - as a list of its child
246    /// XML nodes).
247    ///
248    /// # Panics
249    ///
250    /// This method requires exclusive access to an underlying document store. If there
251    /// is another transaction in process, it will panic. It's advised to define all root shared
252    /// types during the document creation.
253    pub fn get_or_insert_xml_fragment<N: Into<Arc<str>>>(&self, name: N) -> XmlFragmentRef {
254        XmlFragmentRef::root(name).get_or_create(&mut self.transact_mut())
255    }
256
257    /// Subscribe callback function for any changes performed within transaction scope. These
258    /// changes are encoded using lib0 v1 encoding and can be decoded using [Update::decode_v1] if
259    /// necessary or passed to remote peers right away. This callback is triggered on function
260    /// commit.
261    ///
262    /// Returns a subscription, which will unsubscribe function when dropped.
263    #[cfg(feature = "sync")]
264    pub fn observe_update_v1<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
265    where
266        F: Fn(&TransactionMut, &UpdateEvent) + Send + Sync + 'static,
267    {
268        let mut store = self
269            .store
270            .try_write()
271            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
272        let events = store.events.get_or_init();
273        Ok(events.update_v1_events.subscribe(Box::new(f)))
274    }
275
276    /// Subscribe callback function for any changes performed within transaction scope. These
277    /// changes are encoded using lib0 v1 encoding and can be decoded using [Update::decode_v1] if
278    /// necessary or passed to remote peers right away. This callback is triggered on function
279    /// commit.
280    ///
281    /// Returns a subscription, which will unsubscribe function when dropped.
282    #[cfg(not(feature = "sync"))]
283    pub fn observe_update_v1<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
284    where
285        F: Fn(&TransactionMut, &UpdateEvent) + 'static,
286    {
287        let mut store = self
288            .store
289            .try_write()
290            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
291        let events = store.events.get_or_init();
292        Ok(events.update_v1_events.subscribe(Box::new(f)))
293    }
294
295    /// Subscribe callback function for any changes performed within transaction scope. These
296    /// changes are encoded using lib0 v1 encoding and can be decoded using [Update::decode_v1] if
297    /// necessary or passed to remote peers right away. This callback is triggered on function
298    /// commit.
299    ///
300    /// Provided `key` will be used to identify a subscription, which will be used to unsubscribe.
301    #[cfg(feature = "sync")]
302    pub fn observe_update_v1_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
303    where
304        K: Into<Origin>,
305        F: Fn(&TransactionMut, &UpdateEvent) + Send + Sync + 'static,
306    {
307        let mut store = self
308            .store
309            .try_write()
310            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
311        let events = store.events.get_or_init();
312        events
313            .update_v1_events
314            .subscribe_with(key.into(), Box::new(f));
315        Ok(())
316    }
317
318    /// Subscribe callback function for any changes performed within transaction scope. These
319    /// changes are encoded using lib0 v1 encoding and can be decoded using [Update::decode_v1] if
320    /// necessary or passed to remote peers right away. This callback is triggered on function
321    /// commit.
322    ///
323    /// Provided `key` will be used to identify a subscription, which will be used to unsubscribe.
324    #[cfg(not(feature = "sync"))]
325    pub fn observe_update_v1_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
326    where
327        K: Into<Origin>,
328        F: Fn(&TransactionMut, &UpdateEvent) + 'static,
329    {
330        let mut store = self
331            .store
332            .try_write()
333            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
334        let events = store.events.get_or_init();
335        events
336            .update_v1_events
337            .subscribe_with(key.into(), Box::new(f));
338        Ok(())
339    }
340
341    pub fn unobserve_update_v1<K>(&self, key: K) -> Result<bool, TransactionAcqError>
342    where
343        K: Into<Origin>,
344    {
345        let mut store = self
346            .store
347            .try_write()
348            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
349        let events = store.events.get_or_init();
350        Ok(events.update_v1_events.unsubscribe(&key.into()))
351    }
352
353    /// Subscribe callback function for any changes performed within transaction scope. These
354    /// changes are encoded using lib0 v2 encoding and can be decoded using [Update::decode_v2] if
355    /// necessary or passed to remote peers right away. This callback is triggered on function
356    /// commit.
357    ///
358    /// Returns a subscription, which will unsubscribe function when dropped.
359    #[cfg(feature = "sync")]
360    pub fn observe_update_v2<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
361    where
362        F: Fn(&TransactionMut, &UpdateEvent) + Send + Sync + 'static,
363    {
364        let mut store = self
365            .store
366            .try_write()
367            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
368        let events = store.events.get_or_init();
369        Ok(events.update_v2_events.subscribe(Box::new(f)))
370    }
371
372    /// Subscribe callback function for any changes performed within transaction scope. These
373    /// changes are encoded using lib0 v2 encoding and can be decoded using [Update::decode_v2] if
374    /// necessary or passed to remote peers right away. This callback is triggered on function
375    /// commit.
376    ///
377    /// Returns a subscription, which will unsubscribe function when dropped.
378    #[cfg(not(feature = "sync"))]
379    pub fn observe_update_v2<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
380    where
381        F: Fn(&TransactionMut, &UpdateEvent) + 'static,
382    {
383        let mut store = self
384            .store
385            .try_write()
386            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
387        let events = store.events.get_or_init();
388        Ok(events.update_v2_events.subscribe(Box::new(f)))
389    }
390
391    /// Subscribe callback function for any changes performed within transaction scope. These
392    /// changes are encoded using lib0 v2 encoding and can be decoded using [Update::decode_v2] if
393    /// necessary or passed to remote peers right away. This callback is triggered on function
394    /// commit.
395    ///
396    /// Provided `key` will be used to identify a subscription, which will be used to unsubscribe.
397    #[cfg(feature = "sync")]
398    pub fn observe_update_v2_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
399    where
400        K: Into<Origin>,
401        F: Fn(&TransactionMut, &UpdateEvent) + Send + Sync + 'static,
402    {
403        let mut store = self
404            .store
405            .try_write()
406            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
407        let events = store.events.get_or_init();
408        events
409            .update_v2_events
410            .subscribe_with(key.into(), Box::new(f));
411        Ok(())
412    }
413
414    /// Subscribe callback function for any changes performed within transaction scope. These
415    /// changes are encoded using lib0 v2 encoding and can be decoded using [Update::decode_v2] if
416    /// necessary or passed to remote peers right away. This callback is triggered on function
417    /// commit.
418    ///
419    /// Provided `key` will be used to identify a subscription, which will be used to unsubscribe.
420    #[cfg(not(feature = "sync"))]
421    pub fn observe_update_v2_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
422    where
423        K: Into<Origin>,
424        F: Fn(&TransactionMut, &UpdateEvent) + 'static,
425    {
426        let mut store = self
427            .store
428            .try_write()
429            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
430        let events = store.events.get_or_init();
431        events
432            .update_v2_events
433            .subscribe_with(key.into(), Box::new(f));
434        Ok(())
435    }
436
437    pub fn unobserve_update_v2<K>(&self, key: K) -> Result<bool, TransactionAcqError>
438    where
439        K: Into<Origin>,
440    {
441        let mut store = self
442            .store
443            .try_write()
444            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
445        let events = store.events.get_or_init();
446        Ok(events.update_v2_events.unsubscribe(&key.into()))
447    }
448
449    /// Subscribe callback function to updates on the `Doc`. The callback will receive state updates and
450    /// deletions when a document transaction is committed.
451    #[cfg(feature = "sync")]
452    pub fn observe_transaction_cleanup<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
453    where
454        F: Fn(&TransactionMut, &TransactionCleanupEvent) + Send + Sync + 'static,
455    {
456        let mut store = self
457            .store
458            .try_write()
459            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
460        let events = store.events.get_or_init();
461        Ok(events.transaction_cleanup_events.subscribe(Box::new(f)))
462    }
463
464    /// Subscribe callback function to updates on the `Doc`. The callback will receive state updates and
465    /// deletions when a document transaction is committed.
466    #[cfg(not(feature = "sync"))]
467    pub fn observe_transaction_cleanup<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
468    where
469        F: Fn(&TransactionMut, &TransactionCleanupEvent) + 'static,
470    {
471        let mut store = self
472            .store
473            .try_write()
474            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
475        let events = store.events.get_or_init();
476        Ok(events.transaction_cleanup_events.subscribe(Box::new(f)))
477    }
478
479    /// Subscribe callback function to updates on the `Doc`. The callback will receive state updates and
480    /// deletions when a document transaction is committed.
481    #[cfg(feature = "sync")]
482    pub fn observe_transaction_cleanup_with<K, F>(
483        &self,
484        key: K,
485        f: F,
486    ) -> Result<(), TransactionAcqError>
487    where
488        K: Into<Origin>,
489        F: Fn(&TransactionMut, &TransactionCleanupEvent) + Send + Sync + 'static,
490    {
491        let mut store = self
492            .store
493            .try_write()
494            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
495        let events = store.events.get_or_init();
496        events
497            .transaction_cleanup_events
498            .subscribe_with(key.into(), Box::new(f));
499        Ok(())
500    }
501
502    /// Subscribe callback function to updates on the `Doc`. The callback will receive state updates and
503    /// deletions when a document transaction is committed.
504    #[cfg(not(feature = "sync"))]
505    pub fn observe_transaction_cleanup_with<K, F>(
506        &self,
507        key: K,
508        f: F,
509    ) -> Result<(), TransactionAcqError>
510    where
511        K: Into<Origin>,
512        F: Fn(&TransactionMut, &TransactionCleanupEvent) + 'static,
513    {
514        let mut store = self
515            .store
516            .try_write()
517            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
518        let events = store.events.get_or_init();
519        events
520            .transaction_cleanup_events
521            .subscribe_with(key.into(), Box::new(f));
522        Ok(())
523    }
524
525    pub fn unobserve_transaction_cleanup<K>(&self, key: K) -> Result<bool, TransactionAcqError>
526    where
527        K: Into<Origin>,
528    {
529        let mut store = self
530            .store
531            .try_write()
532            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
533        let events = store.events.get_or_init();
534        Ok(events.transaction_cleanup_events.unsubscribe(&key.into()))
535    }
536
537    #[cfg(feature = "sync")]
538    pub fn observe_after_transaction<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
539    where
540        F: Fn(&mut TransactionMut) + Send + Sync + 'static,
541    {
542        let mut store = self
543            .store
544            .try_write()
545            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
546        let events = store.events.get_or_init();
547        Ok(events.after_transaction_events.subscribe(Box::new(f)))
548    }
549
550    #[cfg(feature = "sync")]
551    pub fn observe_after_transaction_with<K, F>(
552        &self,
553        key: K,
554        f: F,
555    ) -> Result<(), TransactionAcqError>
556    where
557        K: Into<Origin>,
558        F: Fn(&mut TransactionMut) + Send + Sync + 'static,
559    {
560        let mut store = self
561            .store
562            .try_write()
563            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
564        let events = store.events.get_or_init();
565        events
566            .after_transaction_events
567            .subscribe_with(key.into(), Box::new(f));
568        Ok(())
569    }
570
571    #[cfg(not(feature = "sync"))]
572    pub fn observe_after_transaction_with<K, F>(
573        &self,
574        key: K,
575        f: F,
576    ) -> Result<(), TransactionAcqError>
577    where
578        K: Into<Origin>,
579        F: Fn(&mut TransactionMut) + 'static,
580    {
581        let mut store = self
582            .store
583            .try_write()
584            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
585        let events = store.events.get_or_init();
586        events
587            .after_transaction_events
588            .subscribe_with(key.into(), Box::new(f));
589        Ok(())
590    }
591
592    pub fn unobserve_after_transaction<K>(&self, key: K) -> Result<bool, TransactionAcqError>
593    where
594        K: Into<Origin>,
595    {
596        let mut store = self
597            .store
598            .try_write()
599            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
600        let events = store.events.get_or_init();
601        Ok(events.after_transaction_events.unsubscribe(&key.into()))
602    }
603
604    /// Subscribe callback function, that will be called whenever a subdocuments inserted in this
605    /// [Doc] will request a load.
606    #[cfg(feature = "sync")]
607    pub fn observe_subdocs<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
608    where
609        F: Fn(&TransactionMut, &SubdocsEvent) + Send + Sync + 'static,
610    {
611        let mut store = self
612            .store
613            .try_write()
614            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
615        let events = store.events.get_or_init();
616        Ok(events.subdocs_events.subscribe(Box::new(f)))
617    }
618
619    /// Subscribe callback function, that will be called whenever a subdocuments inserted in this
620    /// [Doc] will request a load.
621    #[cfg(not(feature = "sync"))]
622    pub fn observe_subdocs<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
623    where
624        F: Fn(&TransactionMut, &SubdocsEvent) + 'static,
625    {
626        let mut store = self
627            .store
628            .try_write()
629            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
630        let events = store.events.get_or_init();
631        Ok(events.subdocs_events.subscribe(Box::new(f)))
632    }
633
634    /// Subscribe callback function, that will be called whenever a subdocuments inserted in this
635    /// [Doc] will request a load.
636    #[cfg(feature = "sync")]
637    pub fn observe_subdocs_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
638    where
639        K: Into<Origin>,
640        F: Fn(&TransactionMut, &SubdocsEvent) + Send + Sync + 'static,
641    {
642        let mut store = self
643            .store
644            .try_write()
645            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
646        let events = store.events.get_or_init();
647        events
648            .subdocs_events
649            .subscribe_with(key.into(), Box::new(f));
650        Ok(())
651    }
652
653    /// Subscribe callback function, that will be called whenever a subdocuments inserted in this
654    /// [Doc] will request a load.
655    #[cfg(not(feature = "sync"))]
656    pub fn observe_subdocs_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
657    where
658        K: Into<Origin>,
659        F: Fn(&TransactionMut, &SubdocsEvent) + 'static,
660    {
661        let mut store = self
662            .store
663            .try_write()
664            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
665        let events = store.events.get_or_init();
666        events
667            .subdocs_events
668            .subscribe_with(key.into(), Box::new(f));
669        Ok(())
670    }
671
672    pub fn unobserve_subdocs<K>(&self, key: K) -> Result<bool, TransactionAcqError>
673    where
674        K: Into<Origin>,
675    {
676        let mut store = self
677            .store
678            .try_write()
679            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
680        let events = store.events.get_or_init();
681        Ok(events.subdocs_events.unsubscribe(&key.into()))
682    }
683
684    /// Subscribe callback function, that will be called whenever a [DocRef::destroy] has been called.
685    #[cfg(feature = "sync")]
686    pub fn observe_destroy<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
687    where
688        F: Fn(&TransactionMut, &Doc) + Send + Sync + 'static,
689    {
690        let mut store = self
691            .store
692            .try_write()
693            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
694        let events = store.events.get_or_init();
695        Ok(events.destroy_events.subscribe(Box::new(f)))
696    }
697
698    /// Subscribe callback function, that will be called whenever a [DocRef::destroy] has been called.
699    #[cfg(not(feature = "sync"))]
700    pub fn observe_destroy<F>(&self, f: F) -> Result<Subscription, TransactionAcqError>
701    where
702        F: Fn(&TransactionMut, &Doc) + 'static,
703    {
704        let mut store = self
705            .store
706            .try_write()
707            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
708        let events = store.events.get_or_init();
709        Ok(events.destroy_events.subscribe(Box::new(f)))
710    }
711
712    /// Subscribe callback function, that will be called whenever a [DocRef::destroy] has been called.
713    #[cfg(feature = "sync")]
714    pub fn observe_destroy_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
715    where
716        K: Into<Origin>,
717        F: Fn(&TransactionMut, &Doc) + Send + Sync + 'static,
718    {
719        let mut store = self
720            .store
721            .try_write()
722            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
723        let events = store.events.get_or_init();
724        events
725            .destroy_events
726            .subscribe_with(key.into(), Box::new(f));
727        Ok(())
728    }
729
730    pub fn unobserve_destroy<K>(&self, key: K) -> Result<bool, TransactionAcqError>
731    where
732        K: Into<Origin>,
733    {
734        let mut store = self
735            .store
736            .try_write()
737            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
738        let events = store.events.get_or_init();
739        Ok(events.destroy_events.unsubscribe(&key.into()))
740    }
741
742    /// Subscribe callback function, that will be called whenever a [DocRef::destroy] has been called.
743    #[cfg(not(feature = "sync"))]
744    pub fn observe_destroy_with<K, F>(&self, key: K, f: F) -> Result<(), TransactionAcqError>
745    where
746        K: Into<Origin>,
747        F: Fn(&TransactionMut, &Doc) + 'static,
748    {
749        let mut store = self
750            .store
751            .try_write()
752            .ok_or(TransactionAcqError::ExclusiveAcqFailed)?;
753        let events = store.events.get_or_init();
754        events
755            .destroy_events
756            .subscribe_with(key.into(), Box::new(f));
757        Ok(())
758    }
759
760    /// Sends a load request to a parent document. Works only if current document is a sub-document
761    /// of a document.
762    pub fn load<T>(&self, parent_txn: &mut T)
763    where
764        T: WriteTxn,
765    {
766        let should_load = self.store.set_should_load(true);
767        if !should_load {
768            let txn = self.transact();
769            if txn.store().is_subdoc() {
770                parent_txn
771                    .subdocs_mut()
772                    .loaded
773                    .insert(self.addr(), self.clone());
774            }
775        }
776    }
777
778    /// Starts destroy procedure for a current document, triggering an "destroy" callback and
779    /// invalidating all event callback subscriptions.
780    pub fn destroy<T>(&self, parent_txn: &mut T)
781    where
782        T: WriteTxn,
783    {
784        let mut txn = self.transact_mut();
785        let store = txn.store_mut();
786        let subdocs: Vec<_> = store.subdocs.values().cloned().collect();
787        for subdoc in subdocs {
788            subdoc.destroy(&mut txn);
789        }
790        if let Some(mut item) = txn.store.parent.take() {
791            let parent_ref = item.clone();
792            let is_deleted = item.is_deleted();
793            if let ItemContent::Doc(_, content) = &mut item.content {
794                let mut options = (**content.store.options()).clone();
795                options.should_load = false;
796                let new_ref = Doc::subdoc(parent_ref, options);
797                if !is_deleted {
798                    parent_txn
799                        .subdocs_mut()
800                        .added
801                        .insert(new_ref.addr(), new_ref.clone());
802                }
803                parent_txn
804                    .subdocs_mut()
805                    .removed
806                    .insert(new_ref.addr(), new_ref.clone());
807
808                *content = new_ref;
809            }
810        }
811        // super.destroy(): cleanup the events
812        if let Some(events) = txn.store_mut().events.take() {
813            events.destroy_events.trigger(|cb| cb(&txn, self));
814        }
815    }
816
817    /// If current document has been inserted as a sub-document, returns a reference to a parent
818    /// document, which contains it.
819    pub fn parent_doc(&self) -> Option<Doc> {
820        let txn = self.transact();
821        txn.parent_doc()
822    }
823
824    pub fn branch_id(&self) -> Option<BranchID> {
825        let txn = self.transact();
826        txn.branch_id()
827    }
828
829    pub fn ptr_eq(a: &Doc, b: &Doc) -> bool {
830        Arc::ptr_eq(&a.store.0, &b.store.0)
831    }
832
833    pub(crate) fn addr(&self) -> DocAddr {
834        DocAddr::new(&self)
835    }
836}
837
838impl PartialEq for Doc {
839    fn eq(&self, other: &Self) -> bool {
840        self.guid() == other.guid()
841    }
842}
843
844impl std::fmt::Display for Doc {
845    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
846        write!(f, "Doc(id: {}, guid: {})", self.client_id(), self.guid())
847    }
848}
849
850impl TryFrom<ItemPtr> for Doc {
851    type Error = ItemPtr;
852
853    fn try_from(item: ItemPtr) -> Result<Self, Self::Error> {
854        if let ItemContent::Doc(_, doc) = &item.content {
855            Ok(doc.clone())
856        } else {
857            Err(item)
858        }
859    }
860}
861
862impl Default for Doc {
863    fn default() -> Self {
864        Doc::new()
865    }
866}
867
868impl ToJson for Doc {
869    fn to_json<T: ReadTxn>(&self, txn: &T) -> Any {
870        let mut m = HashMap::new();
871        for (key, value) in txn.root_refs() {
872            m.insert(key.to_string(), value.to_json(txn));
873        }
874        Any::from(m)
875    }
876}
877
878/// Configuration options of [Doc] instance.
879#[derive(Debug, Clone, PartialEq, Eq)]
880pub struct Options {
881    /// Globally unique client identifier. This value must be unique across all active collaborating
882    /// peers, otherwise a update collisions will happen, causing document store state to be corrupted.
883    ///
884    /// Default value: randomly generated.
885    pub client_id: ClientID,
886    /// A globally unique identifier for this document.
887    ///
888    /// Default value: randomly generated UUID v4.
889    pub guid: Uuid,
890    /// Associate this document with a collection. This only plays a role if your provider has
891    /// a concept of collection.
892    ///
893    /// Default value: `None`.
894    pub collection_id: Option<Arc<str>>,
895    /// How to we count offsets and lengths used in text operations.
896    ///
897    /// Default value: [OffsetKind::Bytes].
898    pub offset_kind: OffsetKind,
899    /// Determines if transactions commits should try to perform GC-ing of deleted items.
900    ///
901    /// Default value: `false`.
902    pub skip_gc: bool,
903    /// If a subdocument, automatically load document. If this is a subdocument, remote peers will
904    /// load the document as well automatically.
905    ///
906    /// Default value: `false`.
907    pub auto_load: bool,
908    /// Whether the document should be synced by the provider now.
909    /// This is toggled to true when you call ydoc.load().
910    ///
911    /// Default value: `true`.
912    pub should_load: bool,
913}
914
915impl Options {
916    pub fn with_client_id(client_id: ClientID) -> Self {
917        Options {
918            client_id,
919            guid: uuid_v4(),
920            collection_id: None,
921            offset_kind: OffsetKind::Bytes,
922            skip_gc: false,
923            auto_load: false,
924            should_load: true,
925        }
926    }
927
928    pub fn with_guid_and_client_id(guid: Uuid, client_id: ClientID) -> Self {
929        Options {
930            client_id,
931            guid,
932            collection_id: None,
933            offset_kind: OffsetKind::Bytes,
934            skip_gc: false,
935            auto_load: false,
936            should_load: true,
937        }
938    }
939
940    fn as_any(&self) -> Any {
941        let mut m = HashMap::new();
942        m.insert("gc".to_owned(), (!self.skip_gc).into());
943        if let Some(collection_id) = self.collection_id.as_ref() {
944            m.insert("collectionId".to_owned(), collection_id.clone().into());
945        }
946        let encoding = match self.offset_kind {
947            OffsetKind::Bytes => 1,
948            OffsetKind::Utf16 => 0, // 0 for compatibility with Yjs, which doesn't have this option
949        };
950        m.insert("encoding".to_owned(), Any::BigInt(encoding));
951        m.insert("autoLoad".to_owned(), self.auto_load.into());
952        m.insert("shouldLoad".to_owned(), self.should_load.into());
953        Any::from(m)
954    }
955}
956
957impl Default for Options {
958    fn default() -> Self {
959        let mut rng = fastrand::Rng::new();
960        let client_id: u32 = rng.u32(0..u32::MAX);
961        let uuid = uuid_v4_from(&mut rng);
962        Self::with_guid_and_client_id(uuid, client_id as ClientID)
963    }
964}
965
966impl Encode for Options {
967    fn encode<E: Encoder>(&self, encoder: &mut E) {
968        let guid = self.guid.to_string();
969        encoder.write_string(&guid);
970        encoder.write_any(&self.as_any())
971    }
972}
973
974impl Decode for Options {
975    fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, Error> {
976        let mut options = Options::default();
977        options.should_load = false; // for decoding shouldLoad is false by default
978        let guid = decoder.read_string()?;
979        options.guid = guid.into();
980
981        if let Any::Map(opts) = decoder.read_any()? {
982            for (k, v) in opts.iter() {
983                match (k.as_str(), v) {
984                    ("gc", Any::Bool(gc)) => options.skip_gc = !*gc,
985                    ("autoLoad", Any::Bool(auto_load)) => options.auto_load = *auto_load,
986                    ("collectionId", Any::String(cid)) => options.collection_id = Some(cid.clone()),
987                    ("encoding", Any::BigInt(1)) => options.offset_kind = OffsetKind::Bytes,
988                    ("encoding", _) => options.offset_kind = OffsetKind::Utf16,
989                    _ => { /* do nothing */ }
990                }
991            }
992        }
993
994        Ok(options)
995    }
996}
997
998/// Determines how string length and offsets of [Text]/[XmlText] are being determined.
999#[repr(u8)]
1000#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1001pub enum OffsetKind {
1002    /// Compute editable strings length and offset using UTF-8 byte count.
1003    Bytes,
1004    /// Compute editable strings length and offset using UTF-16 chars count.
1005    Utf16,
1006}
1007
1008impl Prelim for Doc {
1009    type Return = Doc;
1010
1011    fn into_content(self, txn: &mut TransactionMut) -> (ItemContent, Option<Self>) {
1012        if txn.parent_doc().is_some() {
1013            panic!("Cannot integrate the document, because it's already being used as a sub-document elsewhere");
1014        }
1015        (ItemContent::Doc(None, self), None)
1016    }
1017
1018    fn integrate(self, _txn: &mut TransactionMut, _inner_ref: BranchPtr) {}
1019}
1020
1021/// For a Yjs compatibility reasons we expect subdocuments to be compared based on their reference
1022/// equality. This concept however doesn't really exists in Rust. Therefore we use a store reference
1023/// instead and specialize it for this single scenario.
1024#[repr(transparent)]
1025#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
1026pub(crate) struct DocAddr(usize);
1027
1028impl DocAddr {
1029    pub fn new(doc: &Doc) -> Self {
1030        let ptr = Arc::as_ptr(&doc.store.0);
1031        DocAddr(ptr as usize)
1032    }
1033}
1034
1035#[cfg(test)]
1036mod test {
1037    use crate::block::{BlockCell, ItemContent, GC};
1038    use crate::branch::{Branch, BranchPtr};
1039    use crate::test_utils::exchange_updates;
1040    use crate::transaction::{ReadTxn, TransactionMut};
1041    use crate::types::ToJson;
1042    use crate::update::Update;
1043    use crate::updates::decoder::Decode;
1044    use crate::updates::encoder::{Encode, Encoder, EncoderV1};
1045    use crate::{
1046        any, Any, Array, ArrayPrelim, ArrayRef, BranchID, DeleteSet, Doc, GetString, Map,
1047        MapPrelim, MapRef, OffsetKind, Options, SharedRef, StateVector, Subscription, Text,
1048        TextPrelim, TextRef, Transact, Uuid, WriteTxn, XmlElementPrelim, XmlFragment,
1049        XmlFragmentRef, XmlTextPrelim, XmlTextRef, ID,
1050    };
1051    use arc_swap::ArcSwapOption;
1052    use assert_matches2::assert_matches;
1053    use std::collections::BTreeSet;
1054    use std::iter::FromIterator;
1055    use std::sync::atomic::{AtomicU32, Ordering};
1056    use std::sync::{Arc, Mutex};
1057
1058    #[test]
1059    fn apply_update_basic_v1() {
1060        /* Result of calling following code:
1061        ```javascript
1062        const doc = new Y.Doc()
1063        const ytext = doc.getText('type')
1064        doc.transact(function () {
1065            for (let i = 0; i < 3; i++) {
1066                ytext.insert(0, (i % 10).toString())
1067            }
1068        })
1069        const update = Y.encodeStateAsUpdate(doc)
1070        ```
1071         */
1072        let update = &[
1073            1, 3, 227, 214, 245, 198, 5, 0, 4, 1, 4, 116, 121, 112, 101, 1, 48, 68, 227, 214, 245,
1074            198, 5, 0, 1, 49, 68, 227, 214, 245, 198, 5, 1, 1, 50, 0,
1075        ];
1076        let doc = Doc::new();
1077        let txt = doc.get_or_insert_text("type");
1078        let mut txn = doc.transact_mut();
1079        txn.apply_update(Update::decode_v1(update).unwrap())
1080            .unwrap();
1081
1082        let actual = txt.get_string(&txn);
1083        assert_eq!(actual, "210".to_owned());
1084    }
1085
1086    #[test]
1087    fn apply_update_basic_v2() {
1088        /* Result of calling following code:
1089        ```javascript
1090        const doc = new Y.Doc()
1091        const ytext = doc.getText('type')
1092        doc.transact(function () {
1093            for (let i = 0; i < 3; i++) {
1094                ytext.insert(0, (i % 10).toString())
1095            }
1096        })
1097        const update = Y.encodeStateAsUpdateV2(doc)
1098        ```
1099         */
1100        let update = &[
1101            0, 0, 6, 195, 187, 207, 162, 7, 1, 0, 2, 0, 2, 3, 4, 0, 68, 11, 7, 116, 121, 112, 101,
1102            48, 49, 50, 4, 65, 1, 1, 1, 0, 0, 1, 3, 0, 0,
1103        ];
1104        let doc = Doc::new();
1105        let txt = doc.get_or_insert_text("type");
1106        let mut txn = doc.transact_mut();
1107        txn.apply_update(Update::decode_v2(update).unwrap())
1108            .unwrap();
1109
1110        let actual = txt.get_string(&txn);
1111        assert_eq!(actual, "210".to_owned());
1112    }
1113
1114    #[test]
1115    fn encode_basic() {
1116        let doc = Doc::with_client_id(1490905955);
1117        let txt = doc.get_or_insert_text("type");
1118        let mut t = doc.transact_mut();
1119        txt.insert(&mut t, 0, "0");
1120        txt.insert(&mut t, 0, "1");
1121        txt.insert(&mut t, 0, "2");
1122
1123        let encoded = t.encode_state_as_update_v1(&StateVector::default());
1124        let expected = &[
1125            1, 3, 227, 214, 245, 198, 5, 0, 4, 1, 4, 116, 121, 112, 101, 1, 48, 68, 227, 214, 245,
1126            198, 5, 0, 1, 49, 68, 227, 214, 245, 198, 5, 1, 1, 50, 0,
1127        ];
1128        assert_eq!(encoded.as_slice(), expected);
1129    }
1130
1131    #[test]
1132    fn integrate() {
1133        // create new document at A and add some initial text to it
1134        let d1 = Doc::new();
1135        let txt = d1.get_or_insert_text("test");
1136        let mut t1 = d1.transact_mut();
1137        // Question: why YText.insert uses positions of blocks instead of actual cursor positions
1138        // in text as seen by user?
1139        txt.insert(&mut t1, 0, "hello");
1140        txt.insert(&mut t1, 5, " ");
1141        txt.insert(&mut t1, 6, "world");
1142
1143        assert_eq!(txt.get_string(&t1), "hello world".to_string());
1144
1145        // create document at B
1146        let d2 = Doc::new();
1147        let txt = d2.get_or_insert_text("test");
1148        let mut t2 = d2.transact_mut();
1149        let sv = t2.state_vector().encode_v1();
1150
1151        // create an update A->B based on B's state vector
1152        let mut encoder = EncoderV1::new();
1153        t1.encode_diff(
1154            &StateVector::decode_v1(sv.as_slice()).unwrap(),
1155            &mut encoder,
1156        );
1157        let binary = encoder.to_vec();
1158
1159        // decode an update incoming from A and integrate it at B
1160        let update = Update::decode_v1(binary.as_slice()).unwrap();
1161        let pending = update.integrate(&mut t2).unwrap();
1162
1163        assert!(pending.0.is_none());
1164        assert!(pending.1.is_none());
1165
1166        // check if B sees the same thing that A does
1167        assert_eq!(txt.get_string(&t1), "hello world".to_string());
1168    }
1169
1170    #[test]
1171    fn on_update() {
1172        let counter = Arc::new(AtomicU32::new(0));
1173        let doc = Doc::new();
1174        let doc2 = Doc::new();
1175        let c = counter.clone();
1176        let sub = doc2.observe_update_v1(move |_, e| {
1177            let u = Update::decode_v1(&e.update).unwrap();
1178            for block in u.blocks.blocks() {
1179                c.fetch_add(block.len(), Ordering::SeqCst);
1180            }
1181        });
1182        let txt = doc.get_or_insert_text("test");
1183        let mut txn = doc.transact_mut();
1184        {
1185            txt.insert(&mut txn, 0, "abc");
1186            let mut txn2 = doc2.transact_mut();
1187            let sv = txn2.state_vector().encode_v1();
1188            let u = txn.encode_diff_v1(&StateVector::decode_v1(sv.as_slice()).unwrap());
1189            txn2.apply_update(Update::decode_v1(u.as_slice()).unwrap())
1190                .unwrap();
1191        }
1192        assert_eq!(counter.load(Ordering::SeqCst), 3); // update has been propagated
1193
1194        drop(sub);
1195
1196        {
1197            txt.insert(&mut txn, 3, "de");
1198            let mut txn2 = doc2.transact_mut();
1199            let sv = txn2.state_vector().encode_v1();
1200            let u = txn.encode_diff_v1(&StateVector::decode_v1(sv.as_slice()).unwrap());
1201            txn2.apply_update(Update::decode_v1(u.as_slice()).unwrap())
1202                .unwrap();
1203        }
1204        assert_eq!(counter.load(Ordering::SeqCst), 3); // since subscription has been dropped, update was not propagated
1205    }
1206
1207    #[test]
1208    fn pending_update_integration() {
1209        let doc = Doc::new();
1210        let txt = doc.get_or_insert_text("source");
1211
1212        let updates = [
1213            vec![
1214                1, 2, 242, 196, 218, 129, 3, 0, 40, 1, 5, 115, 116, 97, 116, 101, 5, 100, 105, 114,
1215                116, 121, 1, 121, 40, 1, 7, 99, 111, 110, 116, 101, 120, 116, 4, 112, 97, 116, 104,
1216                1, 119, 13, 117, 110, 116, 105, 116, 108, 101, 100, 52, 46, 116, 120, 116, 0,
1217            ],
1218            vec![
1219                1, 1, 242, 196, 218, 129, 3, 2, 40, 1, 7, 99, 111, 110, 116, 101, 120, 116, 13,
1220                108, 97, 115, 116, 95, 109, 111, 100, 105, 102, 105, 101, 100, 1, 119, 27, 50, 48,
1221                50, 50, 45, 48, 52, 45, 49, 51, 84, 49, 48, 58, 49, 48, 58, 53, 55, 46, 48, 55, 51,
1222                54, 50, 51, 90, 0,
1223            ],
1224            vec![
1225                1, 2, 242, 196, 218, 129, 3, 3, 4, 1, 6, 115, 111, 117, 114, 99, 101, 1, 97, 168,
1226                242, 196, 218, 129, 3, 0, 1, 120, 0,
1227            ],
1228            vec![
1229                1, 1, 242, 196, 218, 129, 3, 4, 168, 242, 196, 218, 129, 3, 0, 1, 120, 1, 242, 196,
1230                218, 129, 3, 1, 0, 1,
1231            ],
1232            vec![
1233                1, 1, 152, 182, 129, 244, 193, 193, 227, 4, 0, 168, 242, 196, 218, 129, 3, 4, 1,
1234                121, 1, 242, 196, 218, 129, 3, 2, 0, 1, 4, 1,
1235            ],
1236            vec![
1237                1, 2, 242, 196, 218, 129, 3, 5, 132, 242, 196, 218, 129, 3, 3, 1, 98, 168, 152,
1238                190, 167, 244, 1, 0, 1, 120, 0,
1239            ],
1240            vec![
1241                1, 1, 242, 196, 218, 129, 3, 6, 168, 152, 190, 167, 244, 1, 0, 1, 120, 1, 152, 190,
1242                167, 244, 1, 1, 0, 1,
1243            ],
1244            vec![
1245                1, 1, 242, 196, 218, 129, 3, 7, 132, 242, 196, 218, 129, 3, 5, 1, 99, 0,
1246            ],
1247            vec![
1248                1, 1, 242, 196, 218, 129, 3, 8, 132, 242, 196, 218, 129, 3, 7, 1, 100, 0,
1249            ],
1250        ];
1251
1252        for u in updates {
1253            let mut txn = doc.transact_mut();
1254            let u = Update::decode_v1(u.as_slice()).unwrap();
1255            txn.apply_update(u).unwrap();
1256        }
1257        assert_eq!(txt.get_string(&doc.transact()), "abcd".to_string());
1258    }
1259
1260    #[test]
1261    fn ypy_issue_32() {
1262        let d1 = Doc::with_client_id(1971027812);
1263        let source_1 = d1.get_or_insert_text("source");
1264        source_1.push(&mut d1.transact_mut(), "a");
1265
1266        let updates = [
1267            vec![
1268                1, 2, 201, 210, 153, 56, 0, 40, 1, 5, 115, 116, 97, 116, 101, 5, 100, 105, 114,
1269                116, 121, 1, 121, 40, 1, 7, 99, 111, 110, 116, 101, 120, 116, 4, 112, 97, 116, 104,
1270                1, 119, 13, 117, 110, 116, 105, 116, 108, 101, 100, 52, 46, 116, 120, 116, 0,
1271            ],
1272            vec![
1273                1, 1, 201, 210, 153, 56, 2, 168, 201, 210, 153, 56, 0, 1, 120, 1, 201, 210, 153,
1274                56, 1, 0, 1,
1275            ],
1276            vec![
1277                1, 1, 201, 210, 153, 56, 3, 40, 1, 7, 99, 111, 110, 116, 101, 120, 116, 13, 108,
1278                97, 115, 116, 95, 109, 111, 100, 105, 102, 105, 101, 100, 1, 119, 27, 50, 48, 50,
1279                50, 45, 48, 52, 45, 49, 54, 84, 49, 52, 58, 48, 51, 58, 53, 51, 46, 57, 51, 48, 52,
1280                54, 56, 90, 0,
1281            ],
1282            vec![
1283                1, 1, 201, 210, 153, 56, 4, 168, 201, 210, 153, 56, 2, 1, 121, 1, 201, 210, 153,
1284                56, 1, 2, 1,
1285            ],
1286        ];
1287        for u in updates {
1288            let u = Update::decode_v1(&u).unwrap();
1289            d1.transact_mut().apply_update(u).unwrap();
1290        }
1291
1292        assert_eq!("a", source_1.get_string(&d1.transact()));
1293
1294        let d2 = Doc::new();
1295        let source_2 = d2.get_or_insert_text("source");
1296        let state_2 = d2.transact().state_vector().encode_v1();
1297        let update = d1
1298            .transact()
1299            .encode_state_as_update_v1(&StateVector::decode_v1(&state_2).unwrap());
1300        let update = Update::decode_v1(&update).unwrap();
1301        d2.transact_mut().apply_update(update).unwrap();
1302
1303        assert_eq!("a", source_2.get_string(&d2.transact()));
1304
1305        let update = Update::decode_v1(&[
1306            1, 2, 201, 210, 153, 56, 5, 132, 228, 254, 237, 171, 7, 0, 1, 98, 168, 201, 210, 153,
1307            56, 4, 1, 120, 0,
1308        ])
1309        .unwrap();
1310        d1.transact_mut().apply_update(update).unwrap();
1311        assert_eq!("ab", source_1.get_string(&d1.transact()));
1312
1313        let d3 = Doc::new();
1314        let source_3 = d3.get_or_insert_text("source");
1315        let state_3 = d3.transact().state_vector().encode_v1();
1316        let state_3 = StateVector::decode_v1(&state_3).unwrap();
1317        let update = d1.transact().encode_state_as_update_v1(&state_3);
1318        let update = Update::decode_v1(&update).unwrap();
1319        d3.transact_mut().apply_update(update).unwrap();
1320
1321        assert_eq!("ab", source_3.get_string(&d3.transact()));
1322    }
1323
1324    #[test]
1325    fn observe_transaction_cleanup() {
1326        // Setup
1327        let doc = Doc::new();
1328        let text = doc.get_or_insert_text("test");
1329        let before_state = Arc::new(ArcSwapOption::default());
1330        let after_state = Arc::new(ArcSwapOption::default());
1331        let delete_set = Arc::new(ArcSwapOption::default());
1332        // Create interior mutable references for the callback.
1333        let before_ref = before_state.clone();
1334        let after_ref = after_state.clone();
1335        let delete_ref = delete_set.clone();
1336        // Subscribe callback
1337
1338        let sub: Subscription = doc
1339            .observe_transaction_cleanup(move |_: &TransactionMut, event| {
1340                before_ref.store(Some(event.before_state.clone().into()));
1341                after_ref.store(Some(event.after_state.clone().into()));
1342                delete_ref.store(Some(event.delete_set.clone().into()));
1343            })
1344            .unwrap();
1345
1346        {
1347            let mut txn = doc.transact_mut();
1348
1349            // Update the document
1350            text.insert(&mut txn, 0, "abc");
1351            text.remove_range(&mut txn, 1, 2);
1352            txn.commit();
1353
1354            // Compare values
1355            assert_eq!(
1356                before_state.swap(None),
1357                Some(Arc::new(txn.before_state.clone()))
1358            );
1359            assert_eq!(
1360                after_state.swap(None),
1361                Some(Arc::new(txn.after_state.clone()))
1362            );
1363            assert_eq!(
1364                delete_set.swap(None),
1365                Some(Arc::new(txn.delete_set.clone()))
1366            );
1367        }
1368
1369        // Ensure that the subscription is successfully dropped.
1370        drop(sub);
1371        let mut txn = doc.transact_mut();
1372        text.insert(&mut txn, 0, "should not update");
1373        txn.commit();
1374        assert_ne!(
1375            after_state.swap(None),
1376            Some(Arc::new(txn.after_state.clone()))
1377        );
1378    }
1379
1380    #[test]
1381    fn partially_duplicated_update() {
1382        let d1 = Doc::with_client_id(1);
1383        let txt1 = d1.get_or_insert_text("text");
1384        txt1.insert(&mut d1.transact_mut(), 0, "hello");
1385        let u = d1
1386            .transact()
1387            .encode_state_as_update_v1(&StateVector::default());
1388
1389        let d2 = Doc::with_client_id(2);
1390        let txt2 = d2.get_or_insert_text("text");
1391        d2.transact_mut()
1392            .apply_update(Update::decode_v1(&u).unwrap())
1393            .unwrap();
1394
1395        txt1.insert(&mut d1.transact_mut(), 5, "world");
1396        let u = d1
1397            .transact()
1398            .encode_state_as_update_v1(&StateVector::default());
1399        d2.transact_mut()
1400            .apply_update(Update::decode_v1(&u).unwrap())
1401            .unwrap();
1402
1403        assert_eq!(
1404            txt1.get_string(&d1.transact()),
1405            txt2.get_string(&d2.transact())
1406        );
1407    }
1408
1409    #[test]
1410    fn incremental_observe_update() {
1411        const INPUT: &'static str = "hello";
1412
1413        let d1 = Doc::with_client_id(1);
1414        let txt1 = d1.get_or_insert_text("text");
1415        let acc = Arc::new(Mutex::new(String::new()));
1416
1417        let a = acc.clone();
1418        let _sub = d1.observe_update_v1(move |_: &TransactionMut, e| {
1419            let u = Update::decode_v1(&e.update).unwrap();
1420            for mut block in u.blocks.into_blocks(false) {
1421                match block.as_item_ptr().as_deref() {
1422                    Some(item) => {
1423                        if let ItemContent::String(s) = &item.content {
1424                            // each character is appended in individual transaction 1-by-1,
1425                            // therefore each update should contain a single string with only
1426                            // one element
1427                            let mut aref = a.lock().unwrap();
1428                            aref.push_str(s.as_str());
1429                        } else {
1430                            panic!("unexpected content type")
1431                        }
1432                    }
1433                    _ => {}
1434                }
1435            }
1436        });
1437
1438        for c in INPUT.chars() {
1439            // append characters 1-by-1 (1 transactions per character)
1440            txt1.push(&mut d1.transact_mut(), &c.to_string());
1441        }
1442
1443        assert_eq!(acc.lock().unwrap().as_str(), INPUT);
1444
1445        // test incremental deletes
1446        let acc = Arc::new(Mutex::new(vec![]));
1447        let a = acc.clone();
1448        let _sub = d1.observe_update_v1(move |_: &TransactionMut, e| {
1449            let u = Update::decode_v1(&e.update).unwrap();
1450            for (&client_id, range) in u.delete_set.iter() {
1451                if client_id == 1 {
1452                    let mut aref = a.lock().unwrap();
1453                    for r in range.iter() {
1454                        aref.push(r.clone());
1455                    }
1456                }
1457            }
1458        });
1459
1460        for _ in 0..INPUT.len() as u32 {
1461            txt1.remove_range(&mut d1.transact_mut(), 0, 1);
1462        }
1463
1464        let expected = vec![(0..1), (1..2), (2..3), (3..4), (4..5)];
1465        assert_eq!(&*acc.lock().unwrap(), &expected);
1466    }
1467
1468    #[test]
1469    fn ycrdt_issue_174() {
1470        let doc = Doc::new();
1471        let bin = &[
1472            0, 0, 11, 176, 133, 128, 149, 31, 205, 190, 199, 196, 21, 7, 3, 0, 3, 5, 0, 17, 168, 1,
1473            8, 0, 40, 0, 8, 0, 40, 0, 8, 0, 40, 0, 33, 1, 39, 110, 91, 49, 49, 49, 114, 111, 111,
1474            116, 105, 51, 50, 114, 111, 111, 116, 115, 116, 114, 105, 110, 103, 114, 111, 111, 116,
1475            97, 95, 108, 105, 115, 116, 114, 111, 111, 116, 97, 95, 109, 97, 112, 114, 111, 111,
1476            116, 105, 51, 50, 95, 108, 105, 115, 116, 114, 111, 111, 116, 105, 51, 50, 95, 109, 97,
1477            112, 114, 111, 111, 116, 115, 116, 114, 105, 110, 103, 95, 108, 105, 115, 116, 114,
1478            111, 111, 116, 115, 116, 114, 105, 110, 103, 95, 109, 97, 112, 65, 1, 4, 3, 4, 6, 4, 6,
1479            4, 5, 4, 8, 4, 7, 4, 11, 4, 10, 3, 0, 5, 1, 6, 0, 1, 0, 1, 0, 1, 2, 65, 8, 2, 8, 0,
1480            125, 2, 119, 5, 119, 111, 114, 108, 100, 118, 2, 1, 98, 119, 1, 97, 1, 97, 125, 1, 118,
1481            2, 1, 98, 119, 1, 98, 1, 97, 125, 2, 125, 1, 125, 2, 119, 1, 97, 119, 1, 98, 8, 0, 1,
1482            141, 223, 163, 226, 10, 1, 0, 1,
1483        ];
1484        let update = Update::decode_v2(bin).unwrap();
1485        doc.transact_mut().apply_update(update).unwrap();
1486
1487        let root = doc.get_or_insert_map("root");
1488        let actual = root.to_json(&doc.transact());
1489        let expected = Any::from_json(
1490            r#"{
1491              "string": "world",
1492              "a_list": [{"b": "a", "a": 1}],
1493              "i32_map": {"1": 2},
1494              "a_map": {
1495                "1": {"a": 2, "b": "b"}
1496              },
1497              "string_list": ["a"],
1498              "i32": 2,
1499              "string_map": {"1": "b"},
1500              "i32_list": [1]
1501            }"#,
1502        )
1503        .unwrap();
1504        assert_eq!(actual, expected);
1505    }
1506
1507    #[test]
1508    fn snapshots_splitting_text() {
1509        let mut options = Options::with_client_id(1);
1510        options.skip_gc = true;
1511
1512        let d1 = Doc::with_options(options);
1513        let txt1 = d1.get_or_insert_text("text");
1514        txt1.insert(&mut d1.transact_mut(), 0, "hello");
1515        let snapshot = d1.transact_mut().snapshot();
1516        txt1.insert(&mut d1.transact_mut(), 5, "_world");
1517
1518        let mut encoder = EncoderV1::new();
1519        d1.transact_mut()
1520            .encode_state_from_snapshot(&snapshot, &mut encoder)
1521            .unwrap();
1522        let update = Update::decode_v1(&encoder.to_vec()).unwrap();
1523
1524        let d2 = Doc::with_client_id(2);
1525        let txt2 = d2.get_or_insert_text("text");
1526        d2.transact_mut().apply_update(update).unwrap();
1527
1528        assert_eq!(txt2.get_string(&d2.transact()), "hello".to_string());
1529    }
1530
1531    #[test]
1532    fn snapshot_non_splitting_text() {
1533        let mut options = Options::default();
1534        options.skip_gc = true;
1535
1536        let doc = Doc::with_options(options.clone().into());
1537        let txt = doc.get_or_insert_text("name");
1538
1539        let mut txn = doc.transact_mut();
1540        txt.insert(&mut txn, 0, "Lucas");
1541        drop(txn);
1542
1543        let txn = doc.transact();
1544        let snapshot = txn.snapshot();
1545
1546        let mut encoder = EncoderV1::new();
1547        txn.encode_state_from_snapshot(&snapshot, &mut encoder)
1548            .unwrap();
1549        let state_diff = encoder.to_vec();
1550
1551        let remote_doc = Doc::with_options(options);
1552        let remote_txt = remote_doc.get_or_insert_text("name");
1553        let mut txn = remote_doc.transact_mut();
1554        let update = Update::decode_v1(&state_diff).unwrap();
1555        txn.apply_update(update).unwrap();
1556
1557        let actual = remote_txt.get_string(&txn);
1558
1559        assert_eq!(actual, "Lucas");
1560    }
1561
1562    #[test]
1563    fn yrb_issue_45() {
1564        let diffs: Vec<Vec<u8>> = vec![
1565            vec![
1566                1, 3, 197, 134, 244, 186, 10, 0, 7, 1, 7, 100, 101, 102, 97, 117, 108, 116, 3, 9,
1567                112, 97, 114, 97, 103, 114, 97, 112, 104, 7, 0, 197, 134, 244, 186, 10, 0, 6, 4, 0,
1568                197, 134, 244, 186, 10, 1, 1, 115, 0,
1569            ],
1570            vec![
1571                1, 1, 197, 134, 244, 186, 10, 3, 132, 197, 134, 244, 186, 10, 2, 3, 227, 129, 149,
1572                1, 197, 134, 244, 186, 10, 1, 2, 1,
1573            ],
1574            vec![
1575                1, 4, 197, 134, 244, 186, 10, 0, 7, 1, 7, 100, 101, 102, 97, 117, 108, 116, 3, 9,
1576                112, 97, 114, 97, 103, 114, 97, 112, 104, 7, 0, 197, 134, 244, 186, 10, 0, 6, 1, 0,
1577                197, 134, 244, 186, 10, 1, 1, 132, 197, 134, 244, 186, 10, 2, 3, 227, 129, 149, 1,
1578                197, 134, 244, 186, 10, 1, 2, 1,
1579            ],
1580            vec![
1581                1, 1, 197, 134, 244, 186, 10, 4, 132, 197, 134, 244, 186, 10, 3, 1, 120, 0,
1582            ],
1583            vec![
1584                1, 1, 197, 134, 244, 186, 10, 5, 132, 197, 134, 244, 186, 10, 4, 3, 227, 129, 129,
1585                1, 197, 134, 244, 186, 10, 1, 4, 1,
1586            ],
1587            vec![
1588                1, 1, 197, 134, 244, 186, 10, 6, 132, 197, 134, 244, 186, 10, 5, 1, 107, 0,
1589            ],
1590            vec![
1591                1, 2, 197, 134, 244, 186, 10, 4, 129, 197, 134, 244, 186, 10, 3, 1, 132, 197, 134,
1592                244, 186, 10, 4, 3, 227, 129, 129, 1, 197, 134, 244, 186, 10, 1, 4, 1,
1593            ],
1594            vec![
1595                1, 1, 197, 134, 244, 186, 10, 7, 132, 197, 134, 244, 186, 10, 6, 3, 227, 129, 147,
1596                1, 197, 134, 244, 186, 10, 1, 6, 1,
1597            ],
1598            vec![
1599                1, 2, 197, 134, 244, 186, 10, 6, 129, 197, 134, 244, 186, 10, 5, 1, 132, 197, 134,
1600                244, 186, 10, 6, 3, 227, 129, 147, 1, 197, 134, 244, 186, 10, 1, 6, 1,
1601            ],
1602            vec![
1603                1, 1, 197, 134, 244, 186, 10, 8, 132, 197, 134, 244, 186, 10, 7, 1, 114, 0,
1604            ],
1605            vec![
1606                1, 1, 197, 134, 244, 186, 10, 9, 132, 197, 134, 244, 186, 10, 8, 3, 227, 130, 140,
1607                1, 197, 134, 244, 186, 10, 1, 8, 1,
1608            ],
1609            vec![
1610                1, 1, 197, 134, 244, 186, 10, 8, 132, 197, 134, 244, 186, 10, 7, 1, 114, 0,
1611            ],
1612            vec![
1613                1, 1, 197, 134, 244, 186, 10, 10, 132, 197, 134, 244, 186, 10, 9, 1, 107, 0,
1614            ],
1615            vec![
1616                1, 1, 197, 134, 244, 186, 10, 11, 132, 197, 134, 244, 186, 10, 10, 3, 227, 129,
1617                139, 1, 197, 134, 244, 186, 10, 1, 10, 1,
1618            ],
1619            vec![
1620                1, 1, 197, 134, 244, 186, 10, 12, 132, 197, 134, 244, 186, 10, 11, 1, 114, 0,
1621            ],
1622            vec![
1623                1, 1, 197, 134, 244, 186, 10, 13, 132, 197, 134, 244, 186, 10, 12, 3, 227, 130,
1624                137, 1, 197, 134, 244, 186, 10, 1, 12, 1,
1625            ],
1626            vec![
1627                1, 1, 197, 134, 244, 186, 10, 9, 132, 197, 134, 244, 186, 10, 8, 3, 227, 130, 140,
1628                1, 197, 134, 244, 186, 10, 1, 8, 1,
1629            ],
1630            vec![
1631                1, 1, 197, 134, 244, 186, 10, 10, 132, 197, 134, 244, 186, 10, 9, 1, 107, 0,
1632            ],
1633            vec![
1634                1, 1, 197, 134, 244, 186, 10, 11, 132, 197, 134, 244, 186, 10, 10, 3, 227, 129,
1635                139, 1, 197, 134, 244, 186, 10, 1, 10, 1,
1636            ],
1637            vec![
1638                1, 1, 197, 134, 244, 186, 10, 12, 132, 197, 134, 244, 186, 10, 11, 1, 114, 0,
1639            ],
1640            vec![
1641                1, 1, 197, 134, 244, 186, 10, 14, 132, 197, 134, 244, 186, 10, 13, 1, 98, 0,
1642            ],
1643            vec![
1644                1, 1, 197, 134, 244, 186, 10, 16, 132, 197, 134, 244, 186, 10, 15, 1, 103, 0,
1645            ],
1646            vec![
1647                1, 1, 197, 134, 244, 186, 10, 15, 132, 197, 134, 244, 186, 10, 14, 3, 227, 129,
1648                176, 1, 197, 134, 244, 186, 10, 1, 14, 1,
1649            ],
1650            vec![
1651                1, 1, 197, 134, 244, 186, 10, 17, 132, 197, 134, 244, 186, 10, 16, 3, 227, 129,
1652                144, 1, 197, 134, 244, 186, 10, 1, 16, 1,
1653            ],
1654            vec![
1655                1, 1, 197, 134, 244, 186, 10, 17, 132, 197, 134, 244, 186, 10, 16, 3, 227, 129,
1656                144, 1, 197, 134, 244, 186, 10, 1, 16, 1,
1657            ],
1658            vec![
1659                1, 1, 197, 134, 244, 186, 10, 18, 132, 197, 134, 244, 186, 10, 17, 6, 227, 131,
1660                144, 227, 130, 176, 1, 197, 134, 244, 186, 10, 2, 15, 1, 17, 1,
1661            ],
1662            vec![
1663                1, 1, 197, 134, 244, 186, 10, 20, 132, 197, 134, 244, 186, 10, 19, 1, 103, 0,
1664            ],
1665            vec![
1666                1, 3, 197, 134, 244, 186, 10, 13, 132, 197, 134, 244, 186, 10, 12, 3, 227, 130,
1667                137, 129, 197, 134, 244, 186, 10, 13, 1, 132, 197, 134, 244, 186, 10, 14, 4, 227,
1668                129, 176, 103, 1, 197, 134, 244, 186, 10, 2, 12, 1, 14, 1,
1669            ],
1670            vec![
1671                1, 1, 197, 134, 244, 186, 10, 21, 132, 197, 134, 244, 186, 10, 20, 3, 227, 129,
1672                140, 1, 197, 134, 244, 186, 10, 1, 20, 1,
1673            ],
1674            vec![
1675                1, 1, 197, 134, 244, 186, 10, 23, 132, 197, 134, 244, 186, 10, 22, 3, 227, 129,
1676                170, 1, 197, 134, 244, 186, 10, 1, 22, 1,
1677            ],
1678            vec![
1679                1, 3, 197, 134, 244, 186, 10, 18, 132, 197, 134, 244, 186, 10, 17, 6, 227, 131,
1680                144, 227, 130, 176, 129, 197, 134, 244, 186, 10, 19, 1, 132, 197, 134, 244, 186,
1681                10, 20, 3, 227, 129, 140, 1, 197, 134, 244, 186, 10, 3, 15, 1, 17, 1, 20, 1,
1682            ],
1683            vec![
1684                1, 1, 197, 134, 244, 186, 10, 24, 132, 197, 134, 244, 186, 10, 23, 3, 227, 129,
1685                132, 0,
1686            ],
1687            vec![
1688                1, 1, 197, 134, 244, 186, 10, 22, 132, 197, 134, 244, 186, 10, 21, 1, 110, 0,
1689            ],
1690            vec![
1691                1, 1, 197, 134, 244, 186, 10, 26, 132, 197, 134, 244, 186, 10, 25, 3, 227, 129,
1692                139, 1, 197, 134, 244, 186, 10, 1, 25, 1,
1693            ],
1694            vec![
1695                1, 1, 197, 134, 244, 186, 10, 25, 132, 197, 134, 244, 186, 10, 24, 1, 107, 0,
1696            ],
1697            vec![
1698                1, 4, 197, 134, 244, 186, 10, 22, 129, 197, 134, 244, 186, 10, 21, 1, 132, 197,
1699                134, 244, 186, 10, 22, 6, 227, 129, 170, 227, 129, 132, 129, 197, 134, 244, 186,
1700                10, 24, 1, 132, 197, 134, 244, 186, 10, 25, 3, 227, 129, 139, 1, 197, 134, 244,
1701                186, 10, 2, 22, 1, 25, 1,
1702            ],
1703            vec![
1704                1, 1, 197, 134, 244, 186, 10, 27, 132, 197, 134, 244, 186, 10, 26, 1, 100, 0,
1705            ],
1706            vec![
1707                1, 1, 197, 134, 244, 186, 10, 28, 132, 197, 134, 244, 186, 10, 27, 3, 227, 129,
1708                169, 1, 197, 134, 244, 186, 10, 1, 27, 1,
1709            ],
1710            vec![
1711                1, 2, 197, 134, 244, 186, 10, 27, 129, 197, 134, 244, 186, 10, 26, 1, 132, 197,
1712                134, 244, 186, 10, 27, 3, 227, 129, 169, 1, 197, 134, 244, 186, 10, 1, 27, 1,
1713            ],
1714            vec![
1715                1, 1, 197, 134, 244, 186, 10, 29, 132, 197, 134, 244, 186, 10, 28, 3, 227, 129,
1716                134, 0,
1717            ],
1718            vec![
1719                1, 1, 197, 134, 244, 186, 10, 30, 132, 197, 134, 244, 186, 10, 29, 1, 107, 0,
1720            ],
1721            vec![
1722                1, 1, 197, 134, 244, 186, 10, 29, 132, 197, 134, 244, 186, 10, 28, 3, 227, 129,
1723                134, 0,
1724            ],
1725            vec![
1726                1, 1, 197, 134, 244, 186, 10, 31, 132, 197, 134, 244, 186, 10, 30, 3, 227, 129,
1727                139, 1, 197, 134, 244, 186, 10, 1, 30, 1,
1728            ],
1729            vec![
1730                1, 1, 197, 134, 244, 186, 10, 30, 132, 197, 134, 244, 186, 10, 29, 1, 107, 0,
1731            ],
1732            vec![
1733                1, 1, 197, 134, 244, 186, 10, 31, 132, 197, 134, 244, 186, 10, 30, 3, 227, 129,
1734                139, 1, 197, 134, 244, 186, 10, 1, 30, 1,
1735            ],
1736            vec![
1737                1, 1, 197, 134, 244, 186, 10, 32, 135, 197, 134, 244, 186, 10, 0, 3, 9, 112, 97,
1738                114, 97, 103, 114, 97, 112, 104, 0,
1739            ],
1740            vec![
1741                1, 1, 197, 134, 244, 186, 10, 32, 135, 197, 134, 244, 186, 10, 0, 3, 9, 112, 97,
1742                114, 97, 103, 114, 97, 112, 104, 0,
1743            ],
1744            vec![
1745                1, 2, 197, 134, 244, 186, 10, 33, 7, 0, 197, 134, 244, 186, 10, 32, 6, 4, 0, 197,
1746                134, 244, 186, 10, 33, 1, 107, 0,
1747            ],
1748            vec![
1749                1, 1, 197, 134, 244, 186, 10, 35, 132, 197, 134, 244, 186, 10, 34, 3, 227, 129,
1750                139, 1, 197, 134, 244, 186, 10, 1, 34, 1,
1751            ],
1752            vec![
1753                1, 1, 197, 134, 244, 186, 10, 36, 132, 197, 134, 244, 186, 10, 35, 1, 107, 0,
1754            ],
1755        ];
1756
1757        let doc = Doc::new();
1758        let mut txn = doc.transact_mut();
1759        for diff in diffs {
1760            let u = Update::decode_v1(diff.as_slice()).unwrap();
1761            txn.apply_update(u).unwrap();
1762        }
1763    }
1764
1765    #[test]
1766    fn root_refs() {
1767        let doc = Doc::new();
1768        {
1769            let _txt = doc.get_or_insert_text("text");
1770            let _array = doc.get_or_insert_array("array");
1771            let _map = doc.get_or_insert_map("map");
1772            let _xml_elem = doc.get_or_insert_xml_fragment("xml_elem");
1773        }
1774
1775        let txn = doc.transact();
1776        for (key, value) in txn.root_refs() {
1777            match key {
1778                "text" => assert!(value.cast::<TextRef>().is_ok()),
1779                "array" => assert!(value.cast::<ArrayRef>().is_ok()),
1780                "map" => assert!(value.cast::<MapRef>().is_ok()),
1781                "xml_elem" => assert!(value.cast::<XmlFragmentRef>().is_ok()),
1782                "xml_text" => assert!(value.cast::<XmlTextRef>().is_ok()),
1783                other => panic!("unrecognized root type: '{}'", other),
1784            }
1785        }
1786    }
1787
1788    #[test]
1789    fn integrate_block_with_parent_gc() {
1790        let d1 = Doc::with_client_id(1);
1791        let d2 = Doc::with_client_id(2);
1792        let d3 = Doc::with_client_id(3);
1793
1794        {
1795            let root = d1.get_or_insert_array("array");
1796            let mut txn = d1.transact_mut();
1797            root.push_back(&mut txn, ArrayPrelim::from(["A"]));
1798        }
1799
1800        exchange_updates(&[&d1, &d2, &d3]);
1801
1802        {
1803            let root = d2.get_or_insert_array("array");
1804            let mut t2 = d2.transact_mut();
1805            root.remove(&mut t2, 0);
1806            d1.transact_mut()
1807                .apply_update(Update::decode_v1(&t2.encode_update_v1()).unwrap())
1808                .unwrap();
1809        }
1810
1811        {
1812            let root = d3.get_or_insert_array("array");
1813            let mut t3 = d3.transact_mut();
1814            let a3 = root.get(&t3, 0).unwrap().cast::<ArrayRef>().unwrap();
1815            a3.push_back(&mut t3, "B");
1816            // D1 got update which already removed a3, but this must not cause panic
1817            d1.transact_mut()
1818                .apply_update(Update::decode_v1(&t3.encode_update_v1()).unwrap())
1819                .unwrap();
1820        }
1821
1822        exchange_updates(&[&d1, &d2, &d3]);
1823
1824        let r1 = d1.get_or_insert_array("array").to_json(&d1.transact());
1825        let r2 = d2.get_or_insert_array("array").to_json(&d2.transact());
1826        let r3 = d3.get_or_insert_array("array").to_json(&d3.transact());
1827
1828        assert_eq!(r1, r2);
1829        assert_eq!(r2, r3);
1830        assert_eq!(r3, r1);
1831    }
1832
1833    #[test]
1834    fn subdoc() {
1835        let doc = Doc::with_client_id(1);
1836        let event = Arc::new(ArcSwapOption::default());
1837        let event_c = event.clone();
1838        let _sub = doc.observe_subdocs(move |_, e| {
1839            let added = e.added().map(|d| d.guid().clone()).collect();
1840            let removed = e.removed().map(|d| d.guid().clone()).collect();
1841            let loaded = e.loaded().map(|d| d.guid().clone()).collect();
1842            event_c.store(Some(Arc::new((added, removed, loaded))));
1843        });
1844        let subdocs = doc.get_or_insert_map("mysubdocs");
1845        let uuid_a: Uuid = "A".into();
1846        let doc_a = Doc::with_options({
1847            let mut o = Options::default();
1848            o.guid = uuid_a.clone();
1849            o
1850        });
1851        {
1852            let mut txn = doc.transact_mut();
1853            let doc_a_ref = subdocs.insert(&mut txn, "a", doc_a);
1854            doc_a_ref.load(&mut txn);
1855        }
1856
1857        let actual = event.swap(None);
1858        assert_eq!(
1859            actual,
1860            Some((vec![uuid_a.clone()], vec![], vec![uuid_a.clone()]).into())
1861        );
1862
1863        {
1864            let mut txn = doc.transact_mut();
1865            let doc_a_ref = subdocs.get(&txn, "a").unwrap().cast::<Doc>().unwrap();
1866            doc_a_ref.load(&mut txn);
1867        }
1868        let actual = event.swap(None);
1869        assert_eq!(actual, None);
1870
1871        {
1872            let mut txn = doc.transact_mut();
1873            let doc_a_ref = subdocs.get(&txn, "a").unwrap().cast::<Doc>().unwrap();
1874            doc_a_ref.destroy(&mut txn);
1875        }
1876        let actual = event.swap(None);
1877        assert_eq!(
1878            actual,
1879            Some(Arc::new((
1880                vec![uuid_a.clone()],
1881                vec![uuid_a.clone()],
1882                vec![]
1883            )))
1884        );
1885
1886        {
1887            let mut txn = doc.transact_mut();
1888            let doc_a_ref = subdocs.get(&txn, "a").unwrap().cast::<Doc>().unwrap();
1889            doc_a_ref.load(&mut txn);
1890        }
1891        let actual = event.swap(None);
1892        assert_eq!(
1893            actual,
1894            Some(Arc::new((vec![], vec![], vec![uuid_a.clone()])))
1895        );
1896
1897        let doc_b = Doc::with_options({
1898            let mut o = Options::default();
1899            o.guid = uuid_a.clone();
1900            o.should_load = false;
1901            o
1902        });
1903        subdocs.insert(&mut doc.transact_mut(), "b", doc_b);
1904        let actual = event.swap(None);
1905        assert_eq!(
1906            actual,
1907            Some(Arc::new((vec![uuid_a.clone()], vec![], vec![])))
1908        );
1909
1910        {
1911            let mut txn = doc.transact_mut();
1912            let doc_b_ref = subdocs.get(&txn, "b").unwrap().cast::<Doc>().unwrap();
1913            doc_b_ref.load(&mut txn);
1914        }
1915        let actual = event.swap(None);
1916        assert_eq!(
1917            actual,
1918            Some(Arc::new((vec![], vec![], vec![uuid_a.clone()])))
1919        );
1920
1921        let uuid_c: Uuid = "C".into();
1922        let doc_c = Doc::with_options({
1923            let mut o = Options::default();
1924            o.guid = uuid_c.clone();
1925            o
1926        });
1927        {
1928            let mut txn = doc.transact_mut();
1929            let doc_c_ref = subdocs.insert(&mut txn, "c", doc_c);
1930            doc_c_ref.load(&mut txn);
1931        }
1932        let actual = event.swap(None);
1933        assert_eq!(
1934            actual,
1935            Some(Arc::new((
1936                vec![uuid_c.clone()],
1937                vec![],
1938                vec![uuid_c.clone()]
1939            )))
1940        );
1941
1942        let guids: BTreeSet<_> = doc.transact().subdoc_guids().collect();
1943        assert_eq!(guids, BTreeSet::from([uuid_a.clone(), uuid_c.clone()]));
1944
1945        let data = doc
1946            .transact()
1947            .encode_state_as_update_v1(&StateVector::default());
1948
1949        let doc2 = Doc::new();
1950        let event = Arc::new(ArcSwapOption::default());
1951        let event_c = event.clone();
1952        let _sub = doc2.observe_subdocs(move |_, e| {
1953            let added: Vec<_> = e.added().map(|d| d.guid().clone()).collect();
1954            let removed: Vec<_> = e.removed().map(|d| d.guid().clone()).collect();
1955            let loaded: Vec<_> = e.loaded().map(|d| d.guid().clone()).collect();
1956            event_c.store(Some(Arc::new((added, removed, loaded))));
1957        });
1958        let update = Update::decode_v1(&data).unwrap();
1959        doc2.transact_mut().apply_update(update).unwrap();
1960        let mut actual = event.swap(None).unwrap();
1961        Arc::get_mut(&mut actual).unwrap().0.sort();
1962        assert_eq!(
1963            actual,
1964            Arc::new((
1965                vec![uuid_a.clone(), uuid_a.clone(), uuid_c.clone()],
1966                vec![],
1967                vec![]
1968            ))
1969        );
1970
1971        let subdocs = doc2.transact().get_map("mysubdocs").unwrap();
1972        {
1973            let mut txn = doc2.transact_mut();
1974            let doc_ref = subdocs.get(&mut txn, "a").unwrap().cast::<Doc>().unwrap();
1975            doc_ref.load(&mut txn);
1976        }
1977        let actual = event.swap(None);
1978        assert_eq!(
1979            actual,
1980            Some(Arc::new((vec![], vec![], vec![uuid_a.clone()])))
1981        );
1982
1983        let guids: BTreeSet<_> = doc2.transact().subdoc_guids().collect();
1984        assert_eq!(guids, BTreeSet::from([uuid_a.clone(), uuid_c.clone()]));
1985        {
1986            let mut txn = doc2.transact_mut();
1987            subdocs.remove(&mut txn, "a");
1988        }
1989
1990        let actual = event.swap(None);
1991        assert_eq!(
1992            actual,
1993            Some(Arc::new((vec![], vec![uuid_a.clone()], vec![])))
1994        );
1995
1996        let mut guids: Vec<_> = doc2.transact().subdoc_guids().collect();
1997        guids.sort();
1998        assert_eq!(guids, vec![uuid_a.clone(), uuid_c.clone()]);
1999    }
2000
2001    #[test]
2002    fn subdoc_load_edge_cases() {
2003        let doc = Doc::with_client_id(1);
2004        let array = doc.get_or_insert_array("test");
2005        let subdoc_1 = Doc::new();
2006        let uuid_1 = subdoc_1.guid().clone();
2007
2008        let event = Arc::new(ArcSwapOption::default());
2009        let event_c = event.clone();
2010        let _sub = doc.observe_subdocs(move |_, e| {
2011            let added = e.added().map(|d| d.guid().clone()).collect();
2012            let removed = e.removed().map(|d| d.guid().clone()).collect();
2013            let loaded = e.loaded().map(|d| d.guid().clone()).collect();
2014
2015            event_c.store(Some(Arc::new((added, removed, loaded))));
2016        });
2017        let doc_ref = {
2018            let mut txn = doc.transact_mut();
2019            let doc_ref = array.insert(&mut txn, 0, subdoc_1);
2020            assert!(doc_ref.should_load());
2021            assert!(!doc_ref.auto_load());
2022            doc_ref
2023        };
2024        let last_event = event.swap(None);
2025        assert_eq!(
2026            last_event,
2027            Some((vec![uuid_1.clone()], vec![], vec![uuid_1.clone()]).into())
2028        );
2029
2030        // destroy and check whether lastEvent adds it again to added (it shouldn't)
2031        doc_ref.destroy(&mut doc.transact_mut());
2032        let doc_ref_2 = array
2033            .get(&doc.transact(), 0)
2034            .unwrap()
2035            .cast::<Doc>()
2036            .unwrap();
2037        let uuid_2 = doc_ref_2.guid();
2038        assert!(!Doc::ptr_eq(&doc_ref, &doc_ref_2));
2039
2040        let last_event = event.swap(None);
2041        assert_eq!(
2042            last_event,
2043            Some((vec![uuid_2.clone()], vec![uuid_2.clone()], vec![]).into())
2044        );
2045
2046        // load
2047        doc_ref_2.load(&mut doc.transact_mut());
2048        let last_event = event.swap(None);
2049        assert_eq!(
2050            last_event,
2051            Some(Arc::new((vec![], vec![], vec![uuid_2.clone()])))
2052        );
2053
2054        // apply from remote
2055        let doc2 = Doc::with_client_id(2);
2056        let event_c = event.clone();
2057        let _sub = doc2.observe_subdocs(move |_, e| {
2058            let added = e.added().map(|d| d.guid().clone()).collect();
2059            let removed = e.removed().map(|d| d.guid().clone()).collect();
2060            let loaded = e.loaded().map(|d| d.guid().clone()).collect();
2061
2062            event_c.store(Some(Arc::new((added, removed, loaded))));
2063        });
2064        let u = Update::decode_v1(
2065            &doc.transact()
2066                .encode_state_as_update_v1(&StateVector::default()),
2067        );
2068        doc2.transact_mut().apply_update(u.unwrap()).unwrap();
2069        let doc_ref_3 = {
2070            let array = doc2.get_or_insert_array("test");
2071            array
2072                .get(&doc2.transact(), 0)
2073                .unwrap()
2074                .cast::<Doc>()
2075                .unwrap()
2076        };
2077        assert!(!doc_ref_3.should_load());
2078        assert!(!doc_ref_3.auto_load());
2079        let uuid_3 = doc_ref_3.guid();
2080        let last_event = event.swap(None);
2081        assert_eq!(
2082            last_event,
2083            Some(Arc::new((vec![uuid_3.clone()], vec![], vec![])))
2084        );
2085
2086        // load
2087        doc_ref_3.load(&mut doc2.transact_mut());
2088        assert!(doc_ref_3.should_load());
2089        let last_event = event.swap(None);
2090        assert_eq!(
2091            last_event,
2092            Some(Arc::new((vec![], vec![], vec![uuid_3.clone()])))
2093        );
2094    }
2095
2096    #[test]
2097    fn subdoc_auto_load_edge_cases() {
2098        let doc = Doc::with_client_id(1);
2099        let array = doc.get_or_insert_array("test");
2100        let subdoc_1 = Doc::with_options({
2101            let mut o = Options::default();
2102            o.auto_load = true;
2103            o
2104        });
2105
2106        let event = Arc::new(ArcSwapOption::default());
2107        let event_c = event.clone();
2108        let _sub = doc.observe_subdocs(move |_, e| {
2109            let added = e.added().map(|d| d.guid().clone()).collect();
2110            let removed = e.removed().map(|d| d.guid().clone()).collect();
2111            let loaded = e.loaded().map(|d| d.guid().clone()).collect();
2112
2113            event_c.store(Some(Arc::new((added, removed, loaded))));
2114        });
2115
2116        let subdoc_1 = {
2117            let mut txn = doc.transact_mut();
2118            array.insert(&mut txn, 0, subdoc_1)
2119        };
2120        assert!(subdoc_1.should_load());
2121        assert!(subdoc_1.auto_load());
2122
2123        let uuid_1 = subdoc_1.guid();
2124        let last_event = event.swap(None);
2125        assert_eq!(
2126            last_event,
2127            Some(Arc::new((
2128                vec![uuid_1.clone()],
2129                vec![],
2130                vec![uuid_1.clone()]
2131            )))
2132        );
2133
2134        // destroy and check whether lastEvent adds it again to added (it shouldn't)
2135        subdoc_1.destroy(&mut doc.transact_mut());
2136
2137        let subdoc_2 = array
2138            .get(&doc.transact(), 0)
2139            .unwrap()
2140            .cast::<Doc>()
2141            .unwrap();
2142        let uuid_2 = subdoc_2.guid();
2143        assert!(!Doc::ptr_eq(&subdoc_1, &subdoc_2));
2144
2145        let last_event = event.swap(None);
2146        assert_eq!(
2147            last_event,
2148            Some(Arc::new((
2149                vec![uuid_2.clone()],
2150                vec![uuid_2.clone()],
2151                vec![]
2152            )))
2153        );
2154
2155        subdoc_2.load(&mut doc.transact_mut());
2156        let last_event = event.swap(None);
2157        assert_eq!(
2158            last_event,
2159            Some(Arc::new((vec![], vec![], vec![uuid_2.clone()])))
2160        );
2161
2162        // apply from remote
2163        let doc2 = Doc::with_client_id(2);
2164        let event_c = event.clone();
2165        let _sub = doc2.observe_subdocs(move |_, e| {
2166            let added = e.added().map(|d| d.guid()).collect();
2167            let removed = e.removed().map(|d| d.guid()).collect();
2168            let loaded = e.loaded().map(|d| d.guid()).collect();
2169
2170            event_c.store(Some(Arc::new((added, removed, loaded))));
2171        });
2172        let u = Update::decode_v1(
2173            &doc.transact()
2174                .encode_state_as_update_v1(&StateVector::default()),
2175        );
2176        doc2.transact_mut().apply_update(u.unwrap()).unwrap();
2177        let subdoc_3 = {
2178            let array = doc2.get_or_insert_array("test");
2179            array
2180                .get(&doc2.transact(), 0)
2181                .unwrap()
2182                .cast::<Doc>()
2183                .unwrap()
2184        };
2185        assert!(subdoc_1.should_load());
2186        assert!(subdoc_1.auto_load());
2187        let uuid_3 = subdoc_3.guid();
2188        let last_event = event.swap(None);
2189        assert_eq!(
2190            last_event,
2191            Some(Arc::new((
2192                vec![uuid_3.clone()],
2193                vec![],
2194                vec![uuid_3.clone()]
2195            )))
2196        );
2197    }
2198
2199    #[test]
2200    fn to_json() {
2201        let doc = Doc::new();
2202        let mut txn = doc.transact_mut();
2203        let text = txn.get_or_insert_text("text");
2204        let array = txn.get_or_insert_array("array");
2205        let map = txn.get_or_insert_map("map");
2206        let xml_fragment = txn.get_or_insert_xml_fragment("xml-fragment");
2207        let xml_element = xml_fragment.insert(&mut txn, 0, XmlElementPrelim::empty("xml-element"));
2208        let xml_text = xml_fragment.insert(&mut txn, 0, XmlTextPrelim::new(""));
2209
2210        text.push(&mut txn, "hello");
2211        xml_text.push(&mut txn, "world");
2212        xml_fragment.insert(&mut txn, 0, XmlElementPrelim::empty("div"));
2213        xml_element.insert(&mut txn, 0, XmlElementPrelim::empty("body"));
2214        array.insert_range(&mut txn, 0, [1, 2, 3]);
2215        map.insert(&mut txn, "key1", "value1");
2216
2217        // sub documents cannot use their parent's transaction
2218        let sub_doc = Doc::new();
2219        let sub_text = sub_doc.get_or_insert_text("sub-text");
2220        let sub_doc = map.insert(&mut txn, "sub-doc", sub_doc);
2221        let mut sub_txn = sub_doc.transact_mut();
2222        sub_text.push(&mut sub_txn, "sample");
2223
2224        let actual = doc.to_json(&txn);
2225        let expected = any!({
2226            "text": "hello",
2227            "array": [1,2,3],
2228            "map": {
2229                "key1": "value1",
2230                "sub-doc": {
2231                    "guid": sub_doc.guid().as_ref()
2232                }
2233            },
2234            "xml-fragment": "<div></div>world<xml-element><body></body></xml-element>",
2235        });
2236        assert_eq!(actual, expected);
2237    }
2238
2239    #[test]
2240    fn apply_snapshot_updates() {
2241        let update = {
2242            let doc = Doc::with_options(Options {
2243                client_id: 1,
2244                skip_gc: true,
2245                offset_kind: OffsetKind::Utf16,
2246                ..Options::default()
2247            });
2248            let txt = doc.get_or_insert_text("test");
2249            let mut txn = doc.transact_mut();
2250            txt.insert(&mut txn, 0, "hello");
2251
2252            let snap = txn.snapshot();
2253
2254            txt.insert(&mut txn, 5, " world");
2255
2256            let mut encoder = EncoderV1::new();
2257            txn.encode_state_from_snapshot(&snap, &mut encoder).unwrap();
2258            encoder.to_vec()
2259        };
2260
2261        let doc = Doc::with_client_id(1);
2262        let txt = doc.get_or_insert_text("test");
2263        let mut txn = doc.transact_mut();
2264        txn.apply_update(Update::decode_v1(&update).unwrap())
2265            .unwrap();
2266        let str = txt.get_string(&txn);
2267        assert_eq!(&str, "hello");
2268    }
2269
2270    #[test]
2271    fn out_of_order_updates() {
2272        let updates = Arc::new(Mutex::new(vec![]));
2273
2274        let d1 = Doc::new();
2275        let _sub = {
2276            let updates = updates.clone();
2277            d1.observe_update_v1(move |_, e| {
2278                let mut u = updates.lock().unwrap();
2279                u.push(Update::decode_v1(&e.update).unwrap());
2280            })
2281            .unwrap()
2282        };
2283
2284        let map = d1.get_or_insert_map("map");
2285        map.insert(&mut d1.transact_mut(), "a", 1);
2286        map.insert(&mut d1.transact_mut(), "a", 1.1);
2287        map.insert(&mut d1.transact_mut(), "b", 2);
2288
2289        assert_eq!(map.to_json(&d1.transact()), any!({"a": 1.1, "b": 2}));
2290
2291        let d2 = Doc::new();
2292
2293        {
2294            let mut updates = updates.lock().unwrap();
2295            let u3 = updates.pop().unwrap();
2296            let u2 = updates.pop().unwrap();
2297            let u1 = updates.pop().unwrap();
2298            let mut txn = d2.transact_mut();
2299            txn.apply_update(u1).unwrap();
2300            assert!(txn.store.pending.is_none()); // applied
2301            txn.apply_update(u3).unwrap();
2302            assert!(txn.store.pending.is_some()); // pending update waiting for u2
2303            txn.apply_update(u2).unwrap();
2304            assert!(txn.store.pending.is_none()); // applied after fixing the missing update
2305        }
2306
2307        let map = d2.get_or_insert_map("map");
2308        assert_eq!(map.to_json(&d2.transact()), any!({"a": 1.1, "b": 2}));
2309    }
2310
2311    #[test]
2312    fn encoding_buffer_overflow_errors() {
2313        assert_matches!(
2314            Update::decode_v1(&vec![
2315                0xe4, 0x9c, 0x10, 0x00, 0x05, 0xff, 0xff, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
2316                0x01, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xfe, 0xb8, 0xc2,
2317                0xe9, 0xad, 0x87, 0xd9, 0x12, 0x00, 0x00, 0x01, 0x01, 0xff, 0xed, 0xf6,
2318            ]),
2319            Err(crate::encoding::read::Error::EndOfBuffer(_))
2320        );
2321
2322        assert_matches!(
2323            Update::decode_v2(&vec![
2324                0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00,
2325                0x16, 0x02, 0x00, 0x00, 0x01, 0xfd, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00,
2326            ]),
2327            Err(crate::encoding::read::Error::EndOfBuffer(_))
2328        );
2329        assert_matches!(
2330            Update::decode_v2(&vec![
2331                0xe4, 0x95, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01,
2332                0x00, 0x00, 0xed, 0x01, 0xbe, 0x82, 0xe3, 0xc3, 0x1c, 0x01, 0x02, 0xe4, 0x95, 0x00,
2333                0x00, 0x01, 0x18, 0x00, 0x00, 0x01, 0x18, 0x00, 0x00, 0x01, 0x00, 0x01, 0xed, 0x00,
2334            ]),
2335            Err(crate::encoding::read::Error::InvalidVarInt)
2336        );
2337        assert_matches!(
2338            Update::decode_v2(&vec![
2339                0x8f, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0xaa, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00,
2340                0x16, 0x02, 0x00, 0xe5, 0xc4, 0x43, 0x14, 0xe7, 0xa6, 0x8b, 0x93, 0xae, 0xb5, 0xfd,
2341                0x5d, 0xe8, 0x26, 0x9a, 0x8a, 0x59, 0x00, 0x31, 0xd5, 0x0f, 0x12, 0x01, 0x30, 0x00,
2342                0x00, 0x00,
2343            ]),
2344            Err(crate::encoding::read::Error::EndOfBuffer(_))
2345        );
2346        assert_matches!(
2347            Update::decode_v2(&vec![
2348                0x00, 0x01, 0x23, 0x00, 0x00, 0x00, 0x01, 0x02, 0x81, 0x00, 0x00, 0x10, 0x00, 0xc7,
2349                0xdc, 0x00, 0xc4, 0x7a, 0x80, 0x00, 0x41, 0xab, 0xea, 0xd6, 0x00, 0x01, 0x00, 0x00,
2350                0x01, 0x00, 0x00, 0x84, 0x00, 0x00, 0x10, 0xff, 0xc7, 0xdc, 0xff, 0x00, 0x00, 0x00,
2351            ]),
2352            Err(crate::encoding::read::Error::EndOfBuffer(_))
2353        );
2354    }
2355
2356    #[test]
2357    fn observe_after_transaction() {
2358        let d1 = Doc::with_client_id(1);
2359        let txt1 = d1.get_or_insert_text("text");
2360
2361        let e = Arc::new(ArcSwapOption::default());
2362        let e_copy = e.clone();
2363        d1.observe_after_transaction_with("key", move |txn| {
2364            e_copy.swap(Some(Arc::new((
2365                txn.before_state.clone(),
2366                txn.after_state.clone(),
2367                txn.delete_set.clone(),
2368            ))));
2369        })
2370        .unwrap();
2371
2372        txt1.insert(&mut d1.transact_mut(), 0, "hello world");
2373        let actual = e.swap(None);
2374        assert_eq!(
2375            actual,
2376            Some(Arc::new((
2377                StateVector::default(),
2378                StateVector::from_iter([(1, 11)]),
2379                DeleteSet::default()
2380            )))
2381        );
2382
2383        txt1.remove_range(&mut d1.transact_mut(), 2, 7);
2384        let actual = e.swap(None);
2385        assert_eq!(
2386            actual,
2387            Some(Arc::new((
2388                StateVector::from_iter([(1, 11)]),
2389                StateVector::from_iter([(1, 11)]),
2390                {
2391                    let mut ds = DeleteSet::new();
2392                    ds.insert(ID::new(1, 2), 7);
2393                    ds
2394                }
2395            )))
2396        );
2397
2398        d1.unobserve_after_transaction("key").unwrap();
2399
2400        txt1.insert(&mut d1.transact_mut(), 4, " the door");
2401        let actual = e.swap(None);
2402        assert!(actual.is_none());
2403    }
2404
2405    #[test]
2406    fn force_gc() {
2407        let doc = Doc::with_options(Options {
2408            client_id: 1,
2409            skip_gc: true,
2410            ..Default::default()
2411        });
2412        let map = doc.get_or_insert_map("map");
2413
2414        {
2415            // create some initial data
2416            let mut txn = doc.transact_mut();
2417            let txt = map.insert(&mut txn, "text", TextPrelim::default()); // <1#0>
2418            txt.insert(&mut txn, 0, "c"); // <1#1>
2419            txt.insert(&mut txn, 0, "b"); // <1#2>
2420            txt.insert(&mut txn, 0, "a"); // <1#3>
2421
2422            // drop nested type
2423            map.remove(&mut txn, "text");
2424        }
2425
2426        // verify that skip_gc works and we have access to an original text content
2427        {
2428            let txn = doc.transact();
2429            let mut i = 1;
2430            for c in ["c", "b", "a"] {
2431                let block = txn
2432                    .store()
2433                    .blocks
2434                    .get_block(&ID::new(1, i))
2435                    .unwrap()
2436                    .as_item()
2437                    .unwrap();
2438                assert!(block.is_deleted(), "`abc` should be marked as deleted");
2439                assert_eq!(&block.content, &ItemContent::String(c.into()));
2440                i += 1;
2441            }
2442        }
2443
2444        // force GC and check if original content is hard deleted
2445        doc.transact_mut().force_gc();
2446
2447        let txn = doc.transact();
2448        let block = txn.store().blocks.get_block(&ID::new(1, 1)).unwrap();
2449        assert_eq!(block.len(), 3, "GCed blocks should be squashed");
2450        assert!(block.is_deleted(), "`abc` should be deleted");
2451        assert_matches!(&block, &BlockCell::GC(_));
2452    }
2453}