y-rb 0.6.0-x86_64-linux-gnu

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,64 @@
1
+ use crate::yvalue::YValue;
2
+ use magnus::r_hash::ForEach::Continue;
3
+ use magnus::{exception, Error, RArray, RHash, RString, Symbol, Value};
4
+ use std::sync::Arc;
5
+ use yrs::types::{Attrs, Value as YrsValue};
6
+ use yrs::{Any, Array, Map, TransactionMut};
7
+
8
+ #[derive(Debug, Clone)]
9
+ pub(crate) struct TypeConversionError;
10
+
11
+ pub(crate) fn indifferent_hash_key(key: Value) -> Option<String> {
12
+ RString::from_value(key)
13
+ .map(|v| v.to_string().unwrap())
14
+ .or_else(|| Symbol::from_value(key).map(|v| v.name().unwrap().to_string()))
15
+ }
16
+
17
+ pub(crate) fn map_rhash_to_attrs(hash: RHash) -> Result<Attrs, Error> {
18
+ let mut a: Attrs = Default::default();
19
+
20
+ let result = hash.foreach(|key: Value, value: Value| {
21
+ let k = Arc::from(key.to_string());
22
+ let v = Any::from(YValue::from(value));
23
+
24
+ a.insert(k, v);
25
+
26
+ Ok(Continue)
27
+ });
28
+
29
+ if result.is_err() {
30
+ return Err(Error::new(
31
+ exception::runtime_error(),
32
+ "could not map hash to attrs",
33
+ ));
34
+ }
35
+
36
+ Ok(a)
37
+ }
38
+
39
+ pub(crate) fn convert_yvalue_to_ruby_value(value: YrsValue, tx: &TransactionMut) -> YValue {
40
+ match value {
41
+ YrsValue::Any(val) => YValue::from(val),
42
+ YrsValue::YText(text) => YValue::from(text),
43
+ YrsValue::YXmlElement(el) => YValue::from(el),
44
+ YrsValue::YXmlText(text) => YValue::from(text),
45
+ YrsValue::YArray(val) => {
46
+ let arr = RArray::new();
47
+ for item in val.iter(tx) {
48
+ let val = convert_yvalue_to_ruby_value(item.clone(), tx);
49
+ let val = *val.0.borrow();
50
+ arr.push(val).expect("cannot push item event to array");
51
+ }
52
+ YValue::from(arr)
53
+ }
54
+ YrsValue::YMap(val) => {
55
+ let iter = val.iter(tx).map(|(key, val)| {
56
+ let val = convert_yvalue_to_ruby_value(val.clone(), tx);
57
+ let val = val.0.into_inner();
58
+ (key, val)
59
+ });
60
+ YValue::from(RHash::from_iter(iter))
61
+ }
62
+ v => panic!("cannot map given yrs values to yvalue: {:?}", v),
63
+ }
64
+ }
@@ -0,0 +1,46 @@
1
+ use magnus::r_string::IntoRString;
2
+ use magnus::value::ReprValue;
3
+ use magnus::{value, IntoValue, RArray, RHash, RString, Value};
4
+ use std::borrow::Borrow;
5
+ use std::ops::{Deref, DerefMut};
6
+ use yrs::Any;
7
+
8
+ pub(crate) struct YAny(pub(crate) Any);
9
+
10
+ impl Deref for YAny {
11
+ type Target = Any;
12
+
13
+ fn deref(&self) -> &Self::Target {
14
+ &self.0
15
+ }
16
+ }
17
+
18
+ impl DerefMut for YAny {
19
+ fn deref_mut(&mut self) -> &mut Self::Target {
20
+ &mut self.0
21
+ }
22
+ }
23
+
24
+ impl TryInto<Value> for YAny {
25
+ type Error = ();
26
+
27
+ fn try_into(self) -> Result<Value, Self::Error> {
28
+ return match self.0 {
29
+ Any::Array(_v) => {
30
+ let arr = RArray::new();
31
+ Ok(arr.as_value())
32
+ }
33
+ Any::Map(_v) => {
34
+ let hash = RHash::new();
35
+ Ok(hash.as_value())
36
+ }
37
+ Any::Null => Ok(value::qnil().as_value()),
38
+ Any::Undefined => Ok(value::qnil().as_value()),
39
+ Any::Bool(v) => Ok(v.into_value()),
40
+ Any::Number(v) => Ok(v.into_value()),
41
+ Any::BigInt(v) => Ok(v.into_value()),
42
+ Any::String(v) => Ok(v.into_r_string().as_value()),
43
+ Any::Buffer(v) => Ok(RString::from_slice(v.borrow()).as_value()),
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,191 @@
1
+ use crate::utils::convert_yvalue_to_ruby_value;
2
+ use crate::ytransaction::YTransaction;
3
+ use crate::yvalue::YValue;
4
+ use magnus::block::Proc;
5
+ use magnus::value::Qnil;
6
+ use magnus::{Error, IntoValue, RArray, RHash, Symbol, Value};
7
+ use std::cell::RefCell;
8
+ use yrs::types::Change;
9
+ use yrs::{Any, Array, ArrayRef, Observable};
10
+
11
+ #[magnus::wrap(class = "Y::Array")]
12
+ pub(crate) struct YArray(pub(crate) RefCell<ArrayRef>);
13
+
14
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
15
+ unsafe impl Send for YArray {}
16
+
17
+ impl YArray {
18
+ pub(crate) fn yarray_each(&self, transaction: &YTransaction, block: Proc) -> Result<(), Error> {
19
+ let tx = transaction.transaction();
20
+ let tx = tx.as_ref().unwrap();
21
+
22
+ let arr = self.0.borrow();
23
+ arr.iter(tx).for_each(|val| {
24
+ let yvalue = *convert_yvalue_to_ruby_value(val, tx).0.borrow();
25
+ let args = (yvalue,);
26
+ let _ = block.call::<(Value,), Qnil>(args);
27
+ });
28
+
29
+ Ok(())
30
+ }
31
+
32
+ pub(crate) fn yarray_get(&self, transaction: &YTransaction, index: u32) -> Value {
33
+ let tx = transaction.transaction();
34
+ let tx = tx.as_ref().unwrap();
35
+
36
+ let arr = self.0.borrow();
37
+ let v = arr.get(tx, index).unwrap();
38
+ *convert_yvalue_to_ruby_value(v, tx).0.borrow()
39
+ }
40
+ pub(crate) fn yarray_insert(&self, transaction: &YTransaction, index: u32, value: Value) {
41
+ let yvalue = YValue::from(value);
42
+ let avalue = Any::from(yvalue);
43
+
44
+ let mut tx = transaction.transaction();
45
+ let tx = tx.as_mut().unwrap();
46
+
47
+ let arr = self.0.borrow_mut();
48
+ arr.insert(tx, index, avalue);
49
+ }
50
+ pub(crate) fn yarray_insert_range(
51
+ &self,
52
+ transaction: &YTransaction,
53
+ index: u32,
54
+ values: RArray,
55
+ ) {
56
+ let arr = self.0.borrow_mut();
57
+ let mut tx = transaction.transaction();
58
+ let tx = tx.as_mut().unwrap();
59
+
60
+ let add_values: Vec<Any> = values
61
+ .each()
62
+ .into_iter()
63
+ .map(|value| YValue::from(value.unwrap()).into())
64
+ .collect();
65
+
66
+ arr.insert_range(tx, index, add_values)
67
+ }
68
+ pub(crate) fn yarray_length(&self, transaction: &YTransaction) -> u32 {
69
+ let arr = self.0.borrow();
70
+ let tx = transaction.transaction();
71
+ let tx = tx.as_ref().unwrap();
72
+
73
+ arr.len(tx)
74
+ }
75
+ pub(crate) fn yarray_observe(&self, block: Proc) -> Result<u32, Error> {
76
+ let change_added = Symbol::new("added").to_static();
77
+ let change_retain = Symbol::new("retain").to_static();
78
+ let change_removed = Symbol::new("removed").to_static();
79
+
80
+ // let mut error: Option<Error> = None;
81
+
82
+ let subscription_id = self
83
+ .0
84
+ .borrow_mut()
85
+ .observe(move |transaction, array_event| {
86
+ let delta = array_event.delta(transaction);
87
+ // let mut changes = RArray::with_capacity(delta.len());
88
+ let (changes, errors): (Vec<_>, Vec<_>) = delta
89
+ .iter()
90
+ .map(|change| {
91
+ let payload = RHash::new();
92
+ let result = match change {
93
+ Change::Added(v) => {
94
+ let values = v
95
+ .iter()
96
+ .map(|v| <YValue as Into<Value>>::into(YValue::from(v.clone())))
97
+ .collect::<RArray>();
98
+ payload.aset(change_added, values)
99
+ }
100
+ Change::Retain(position) => {
101
+ payload.aset(change_retain, (*position).into_value())
102
+ }
103
+ Change::Removed(position) => {
104
+ payload.aset(change_removed, (*position).into_value())
105
+ }
106
+ };
107
+
108
+ match result {
109
+ Ok(()) => Ok(payload),
110
+ Err(e) => Err(e),
111
+ }
112
+ })
113
+ .partition(Result::is_ok);
114
+
115
+ if errors.is_empty() {
116
+ let args_changes = RArray::new();
117
+ for change in changes.iter() {
118
+ let c = *change.as_ref().unwrap();
119
+ args_changes
120
+ .push(c)
121
+ .expect("cannot push change event to args");
122
+ }
123
+
124
+ let args = (args_changes,);
125
+ let _ = block.call::<(RArray,), Qnil>(args);
126
+ // todo: make sure we respect the result and bubble up the
127
+ // error so that we can return as part of the Result
128
+ }
129
+
130
+ // todo: make sure we respect errors and let the method fail by
131
+ // by returning a Result containing an Error
132
+ })
133
+ .into();
134
+
135
+ Ok(subscription_id)
136
+ }
137
+ pub(crate) fn yarray_push_back(&self, transaction: &YTransaction, value: Value) {
138
+ let yvalue = YValue::from(value);
139
+ let avalue = Any::from(yvalue);
140
+ let mut tx = transaction.transaction();
141
+ let tx = tx.as_mut().unwrap();
142
+
143
+ self.0.borrow_mut().push_back(tx, avalue);
144
+ }
145
+ pub(crate) fn yarray_push_front(&self, transaction: &YTransaction, value: Value) {
146
+ let yvalue = YValue::from(value);
147
+ let avalue = Any::from(yvalue);
148
+
149
+ let mut tx = transaction.transaction();
150
+ let tx = tx.as_mut().unwrap();
151
+
152
+ let arr = self.0.borrow_mut();
153
+ arr.push_front(tx, avalue);
154
+ }
155
+ pub(crate) fn yarray_remove(&self, transaction: &YTransaction, index: u32) {
156
+ let mut tx = transaction.transaction();
157
+ let tx = tx.as_mut().unwrap();
158
+
159
+ let arr = self.0.borrow_mut();
160
+ arr.remove(tx, index)
161
+ }
162
+ pub(crate) fn yarray_remove_range(&self, transaction: &YTransaction, index: u32, len: u32) {
163
+ let mut tx = transaction.transaction();
164
+ let tx = tx.as_mut().unwrap();
165
+
166
+ let arr = self.0.borrow_mut();
167
+ arr.remove_range(tx, index, len)
168
+ }
169
+ pub(crate) fn yarray_to_a(&self, transaction: &YTransaction) -> RArray {
170
+ let arr = self.0.borrow();
171
+ let tx = transaction.transaction();
172
+ let tx = tx.as_ref().unwrap();
173
+
174
+ let r_arr = RArray::new();
175
+ for item in arr.iter(tx) {
176
+ let r_val = YValue::from(item);
177
+ let r_val = *r_val.0.borrow();
178
+ r_arr.push(r_val).expect("cannot push item event to array");
179
+ }
180
+ r_arr
181
+ }
182
+ pub(crate) fn yarray_unobserve(&self, subscription_id: u32) {
183
+ self.0.borrow_mut().unobserve(subscription_id);
184
+ }
185
+ }
186
+
187
+ impl From<ArrayRef> for YArray {
188
+ fn from(v: ArrayRef) -> Self {
189
+ YArray(RefCell::from(v))
190
+ }
191
+ }
@@ -0,0 +1,39 @@
1
+ use crate::yvalue::YValue;
2
+ use magnus::r_hash::ForEach::Continue;
3
+ use magnus::{RHash, Value};
4
+ use std::cell::RefCell;
5
+ use std::sync::Arc;
6
+ use yrs::types::Attrs;
7
+ use yrs::Any;
8
+
9
+ #[magnus::wrap(class = "Y::Attrs")]
10
+ #[derive(Clone)]
11
+ pub(crate) struct YAttrs(pub(crate) RefCell<Attrs>);
12
+
13
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
14
+ unsafe impl Send for YAttrs {}
15
+
16
+ impl From<Attrs> for YAttrs {
17
+ fn from(value: Attrs) -> Self {
18
+ YAttrs(RefCell::from(value))
19
+ }
20
+ }
21
+
22
+ impl From<RHash> for YAttrs {
23
+ fn from(value: RHash) -> Self {
24
+ let mut attrs = Attrs::new();
25
+
26
+ value
27
+ .foreach(|key: Value, value: Value| {
28
+ let k = key.to_string();
29
+ let yvalue = YValue::from(value);
30
+ let avalue = Any::from(yvalue);
31
+ attrs.insert(Arc::from(k), avalue);
32
+
33
+ Ok(Continue)
34
+ })
35
+ .expect("cannot iterate attributes hash");
36
+
37
+ YAttrs(RefCell::from(attrs))
38
+ }
39
+ }
@@ -0,0 +1,151 @@
1
+ use magnus::{block::Proc, exception, Error, Value};
2
+ use std::borrow::Borrow;
3
+ use std::cell::RefCell;
4
+ use std::collections::HashMap;
5
+ use y_sync::awareness::{Awareness, AwarenessUpdate, Event, UpdateSubscription};
6
+ use yrs::block::ClientID;
7
+ use yrs::updates::decoder::Decode;
8
+ use yrs::updates::encoder::Encode;
9
+ use yrs::{Doc, OffsetKind, Options};
10
+
11
+ #[magnus::wrap(class = "Y::Awareness")]
12
+ pub(crate) struct YAwareness(pub(crate) RefCell<Awareness>);
13
+
14
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
15
+ unsafe impl Send for YAwareness {}
16
+
17
+ impl YAwareness {
18
+ pub(crate) fn yawareness_new() -> Self {
19
+ let mut options = Options {
20
+ offset_kind: OffsetKind::Utf16,
21
+ ..Default::default()
22
+ };
23
+ options.offset_kind = OffsetKind::Utf16;
24
+
25
+ let doc = Doc::with_options(options);
26
+
27
+ let awareness = Awareness::new(doc);
28
+
29
+ Self(RefCell::new(awareness))
30
+ }
31
+
32
+ pub(crate) fn yawareness_apply_update(&self, update: Vec<u8>) -> Result<(), Error> {
33
+ AwarenessUpdate::decode_v1(update.as_slice())
34
+ .map_err(|_error| Error::new(exception::runtime_error(), "cannot decode update"))
35
+ .and_then(|value| {
36
+ self.0.borrow_mut().apply_update(value).map_err(|_error| {
37
+ Error::new(exception::runtime_error(), "cannot apply awareness update")
38
+ })
39
+ })
40
+ }
41
+
42
+ pub(crate) fn yawareness_clean_local_state(&self) {
43
+ self.0.borrow_mut().clean_local_state();
44
+ }
45
+
46
+ pub(crate) fn yawareness_client_id(&self) -> ClientID {
47
+ self.0.borrow().client_id()
48
+ }
49
+
50
+ pub(crate) fn yawareness_clients(&self) -> HashMap<ClientID, String> {
51
+ self.0.borrow().clients().to_owned()
52
+ }
53
+
54
+ pub(crate) fn yawareness_local_state(&self) -> Option<String> {
55
+ self.0.borrow().local_state().map(|value| value.to_string())
56
+ }
57
+
58
+ pub(crate) fn yawareness_on_update(&self, block: Proc) -> YAwarenessSubscription {
59
+ let subscription = self.0.borrow_mut().on_update(move |_awareness, event| {
60
+ let awareness_event = YAwarenessEvent::from(event);
61
+ let args = (awareness_event,);
62
+ block
63
+ .call::<(YAwarenessEvent,), Value>(args)
64
+ .expect("cannot call block: on_update");
65
+ });
66
+
67
+ // we need to make sure the event handler "survives" and is not being
68
+ // dropped after leaving this scope, so we pass it back to Ruby.
69
+ YAwarenessSubscription::from(subscription)
70
+ }
71
+
72
+ pub(crate) fn yawareness_remove_state(&self, client_id: ClientID) {
73
+ self.0.borrow_mut().remove_state(client_id)
74
+ }
75
+
76
+ pub(crate) fn yawareness_set_local_state(&self, json: String) {
77
+ self.0.borrow_mut().set_local_state(json)
78
+ }
79
+
80
+ pub(crate) fn yawareness_update(&self) -> Result<Vec<u8>, Error> {
81
+ self.0
82
+ .borrow_mut()
83
+ .update()
84
+ .map(|update| update.encode_v1())
85
+ .map_err(|_error| {
86
+ Error::new(
87
+ exception::runtime_error(),
88
+ "cannot create update for current state",
89
+ )
90
+ })
91
+ }
92
+
93
+ pub(crate) fn yawareness_update_with_clients(
94
+ &self,
95
+ clients: Vec<ClientID>,
96
+ ) -> Result<Vec<u8>, Error> {
97
+ self.0
98
+ .borrow_mut()
99
+ .update_with_clients(clients)
100
+ .map(|update| update.encode_v1())
101
+ .map_err(|_error| {
102
+ Error::new(
103
+ exception::runtime_error(),
104
+ "cannot create update for current state and given clients",
105
+ )
106
+ })
107
+ }
108
+ }
109
+
110
+ impl From<Awareness> for YAwareness {
111
+ fn from(value: Awareness) -> Self {
112
+ Self(RefCell::from(value))
113
+ }
114
+ }
115
+
116
+ #[magnus::wrap(class = "Y::AwarenessEvent")]
117
+ pub(crate) struct YAwarenessEvent(Event);
118
+
119
+ /// SAFETY: This is safe because we only access this data when the GVL is held.
120
+ unsafe impl Send for YAwarenessEvent {}
121
+
122
+ impl YAwarenessEvent {
123
+ pub(crate) fn added(&self) -> Vec<ClientID> {
124
+ self.0.borrow().added().to_vec()
125
+ }
126
+ pub(crate) fn updated(&self) -> Vec<ClientID> {
127
+ self.0.borrow().updated().to_vec()
128
+ }
129
+ pub(crate) fn removed(&self) -> Vec<ClientID> {
130
+ self.0.borrow().removed().to_vec()
131
+ }
132
+ }
133
+
134
+ impl From<&Event> for YAwarenessEvent {
135
+ fn from(value: &Event) -> Self {
136
+ Self(value.clone())
137
+ }
138
+ }
139
+
140
+ #[magnus::wrap(class = "Y::AwarenessEvent")]
141
+ pub(crate) struct YAwarenessSubscription(UpdateSubscription);
142
+
143
+ unsafe impl Send for YAwarenessSubscription {}
144
+
145
+ impl YAwarenessSubscription {}
146
+
147
+ impl From<UpdateSubscription> for YAwarenessSubscription {
148
+ fn from(v: UpdateSubscription) -> Self {
149
+ YAwarenessSubscription(v)
150
+ }
151
+ }
@@ -0,0 +1,19 @@
1
+ use magnus::{IntoValue, RHash, Value};
2
+
3
+ unsafe impl Send for YDiff {}
4
+
5
+ #[magnus::wrap(class = "Y::Diff")]
6
+ pub(crate) struct YDiff {
7
+ pub(crate) ydiff_insert: Value,
8
+ pub(crate) ydiff_attrs: Option<RHash>,
9
+ }
10
+
11
+ impl YDiff {
12
+ pub(crate) fn ydiff_insert(&self) -> Value {
13
+ self.ydiff_insert
14
+ }
15
+
16
+ pub(crate) fn ydiff_attrs(&self) -> Option<Value> {
17
+ self.ydiff_attrs.as_ref().map(|value| value.into_value())
18
+ }
19
+ }
@@ -0,0 +1,113 @@
1
+ use crate::yarray::YArray;
2
+ use crate::ymap::YMap;
3
+ use crate::ytext::YText;
4
+ use crate::yxml_element::YXmlElement;
5
+ use crate::yxml_fragment::YXmlFragment;
6
+ use crate::yxml_text::YXmlText;
7
+ use crate::YTransaction;
8
+ use magnus::block::Proc;
9
+ use magnus::{exception::runtime_error, Error, Integer, RArray, Value};
10
+ use std::borrow::Borrow;
11
+ use std::cell::RefCell;
12
+ use yrs::updates::decoder::Decode;
13
+ use yrs::updates::encoder::{Encoder, EncoderV2};
14
+ use yrs::{Doc, OffsetKind, Options, ReadTxn, StateVector, SubscriptionId, Transact};
15
+
16
+ #[magnus::wrap(class = "Y::Doc")]
17
+ pub(crate) struct YDoc(pub(crate) RefCell<Doc>);
18
+
19
+ unsafe impl Send for YDoc {}
20
+
21
+ impl YDoc {
22
+ pub(crate) fn ydoc_new(client_id: &[Value]) -> Self {
23
+ let mut options = Options::default();
24
+ if client_id.len() == 1 {
25
+ let value = client_id.first().unwrap();
26
+ options.client_id = Integer::from_value(*value).unwrap().to_u64().unwrap();
27
+ }
28
+ options.offset_kind = OffsetKind::Utf16;
29
+
30
+ let doc = Doc::with_options(options);
31
+ Self(RefCell::new(doc))
32
+ }
33
+
34
+ pub(crate) fn ydoc_encode_diff_v1(
35
+ &self,
36
+ transaction: &YTransaction,
37
+ state_vector: Vec<u8>,
38
+ ) -> Result<Vec<u8>, Error> {
39
+ let mut tx = transaction.transaction();
40
+ let tx = tx.as_mut().unwrap();
41
+
42
+ StateVector::decode_v1(state_vector.borrow())
43
+ .map(|sv| tx.encode_diff_v1(&sv))
44
+ .map_err(|_e| Error::new(runtime_error(), "cannot encode diff"))
45
+ }
46
+
47
+ pub(crate) fn ydoc_encode_diff_v2(
48
+ &self,
49
+ transaction: &YTransaction,
50
+ state_vector: Vec<u8>,
51
+ ) -> Result<Vec<u8>, Error> {
52
+ let mut tx = transaction.transaction();
53
+ let tx = tx.as_mut().unwrap();
54
+ let mut encoder = EncoderV2::new();
55
+
56
+ StateVector::decode_v2(state_vector.borrow())
57
+ .map(|sv| tx.encode_diff(&sv, &mut encoder))
58
+ .map(|_| encoder.to_vec())
59
+ .map_err(|_e| Error::new(runtime_error(), "cannot encode diff"))
60
+ }
61
+
62
+ pub(crate) fn ydoc_get_or_insert_array(&self, name: String) -> YArray {
63
+ let array_ref = self.0.borrow().get_or_insert_array(name.as_str());
64
+ YArray::from(array_ref)
65
+ }
66
+
67
+ pub(crate) fn ydoc_get_or_insert_map(&self, name: String) -> YMap {
68
+ let map_ref = self.0.borrow().get_or_insert_map(name.as_str());
69
+ YMap::from(map_ref)
70
+ }
71
+
72
+ pub(crate) fn ydoc_get_or_insert_text(&self, name: String) -> YText {
73
+ let text_ref = self.0.borrow().get_or_insert_text(name.as_str());
74
+ YText::from(text_ref)
75
+ }
76
+
77
+ pub(crate) fn ydoc_get_or_insert_xml_element(&self, name: String) -> YXmlElement {
78
+ let xml_element_ref = self.0.borrow_mut().get_or_insert_xml_element(name.as_str());
79
+ YXmlElement::from(xml_element_ref) // ::into() maps to YXmlFragment instead of YXmlElement :-(
80
+ }
81
+
82
+ pub(crate) fn ydoc_get_or_insert_xml_fragment(&self, name: String) -> YXmlFragment {
83
+ let xml_fragment_ref = self.0.borrow().get_or_insert_xml_fragment(name.as_str());
84
+ YXmlFragment::from(xml_fragment_ref)
85
+ }
86
+
87
+ pub(crate) fn ydoc_get_or_insert_xml_text(&self, name: String) -> YXmlText {
88
+ let xml_text_ref = self.0.borrow().get_or_insert_xml_text(name.as_str());
89
+ YXmlText::from(xml_text_ref)
90
+ }
91
+
92
+ pub(crate) fn ydoc_transact(&self) -> YTransaction {
93
+ let doc = self.0.borrow();
94
+ let transaction = doc.transact_mut();
95
+ YTransaction::from(transaction)
96
+ }
97
+
98
+ pub(crate) fn ydoc_observe_update(&self, block: Proc) -> Result<SubscriptionId, Error> {
99
+ self.0
100
+ .borrow()
101
+ .observe_update_v1(move |_tx, update_event| {
102
+ let update = update_event.update.to_vec();
103
+ let update = RArray::from_vec(update);
104
+
105
+ let args: (RArray,) = (update,);
106
+ block
107
+ .call::<(RArray,), Value>(args)
108
+ .expect("cannot call update block");
109
+ })
110
+ .map(|v| v.into())
111
+ .map_err(|err| Error::new(runtime_error(), err.to_string()))
112
+ }
113
+ }