1use std::time::{SystemTime, UNIX_EPOCH};
2use mf_model::mark::Mark;
3use mf_model::tree::Tree;
4use mf_state::transaction::Transaction;
5use crate::AwarenessRef;
7use serde_json::Value as JsonValue;
8use yrs::{Map, ReadTxn, Transact};
9use yrs::{
10 types::{array::ArrayRef, map::MapRef, Value},
11 Array, ArrayPrelim, MapPrelim, TransactionMut, WriteTxn,
12};
13
14use crate::ClientResult;
15use mf_model::{node::Node, attrs::Attrs, types::NodeId};
16use std::sync::Arc;
17use std::collections::HashMap;
18use rpds::VectorSync;
19
20pub struct Utils;
22impl Utils {
23 pub fn get_unix_time() -> u64 {
24 SystemTime::now()
25 .duration_since(UNIX_EPOCH)
26 .unwrap_or_default()
27 .as_millis() as u64
28 }
29 pub fn apply_yrs_to_tree(doc: &yrs::Doc) -> ClientResult<Tree> {
32 use mf_model::types::NodeId;
33 use std::collections::HashMap;
34
35 let root_id = Utils::get_root_id_from_yrs_doc(doc)?;
36 let txn = doc.transact();
37 let nodes_map = txn
38 .get_map("nodes")
39 .ok_or(anyhow::anyhow!("Yrs 文档中没有找到 nodes 映射"))?;
40 let mut tree_nodes = HashMap::new();
41 let mut parent_map = HashMap::new();
42
43 Utils::build_tree_nodes_from_yrs(
44 &root_id,
45 &nodes_map,
46 &txn,
47 &mut tree_nodes,
48 &mut parent_map,
49 None,
50 )?;
51
52 let root_node = tree_nodes
53 .get(&NodeId::from(root_id))
54 .ok_or(anyhow::anyhow!("根节点不存在"))?
55 .as_ref()
56 .clone();
57 let root_enum =
58 Utils::build_node_enum_from_map(&root_node, &tree_nodes);
59 Ok(Tree::from(root_enum))
60 }
61 pub async fn apply_tree_to_yrs(
64 awareness_ref: AwarenessRef,
65 tree: &Tree,
66 ) -> ClientResult<()> {
67 let mut awareness = awareness_ref.write().await;
68 let doc = awareness.doc_mut();
69 let mut txn =
70 doc.transact_mut_with(doc.client_id().clone().to_string());
71
72 let nodes_map = txn.get_or_insert_map("nodes");
74 nodes_map.clear(&mut txn);
75
76 Utils::sync_tree_to_yrs(tree, &mut txn)?;
78
79 let meta_map = txn.get_or_insert_map("meta");
81 meta_map.insert(
82 &mut txn,
83 "root_id",
84 yrs::Any::String(tree.root_id.to_string().into()),
85 );
86
87 txn.commit();
89
90 tracing::info!(
91 "成功初始化树,包含 {} 个节点,根节点ID: {}",
92 tree.nodes.iter().map(|shard| shard.keys().len()).sum::<usize>(),
93 tree.root_id
94 );
95 Ok(())
96 }
97
98 pub fn sync_tree_to_yrs(
100 tree: &Tree,
101 txn: &mut yrs::TransactionMut,
102 ) -> ClientResult<()> {
103 use mf_transform::node_step::AddNodeStep;
104
105 if let Some(root_tree) = tree.all_children(&tree.root_id, None) {
107 let add_step = AddNodeStep {
110 parent_id: tree.root_id.clone(),
111 nodes: vec![root_tree],
112 };
113
114 let context = crate::mapping::create_context(
116 "tree_sync_client".to_string(),
117 "tree_sync_user".to_string(),
118 );
119
120 if let Err(e) =
121 crate::mapping::convert_step(&add_step, txn, &context)
122 {
123 tracing::error!("🔄 同步树节点到 Yrs 失败: {}", e);
124 return Err(anyhow::anyhow!(format!(
125 "Failed to sync tree: {}",
126 e
127 )));
128 }
129 }
130
131 Ok(())
132 }
133 pub async fn apply_transaction_to_yrs(
135 awareness_ref: AwarenessRef,
136 transaction: &Transaction,
137 ) -> ClientResult<()> {
138 let mut awareness = awareness_ref.write().await;
141 let doc = awareness.doc_mut();
142 let mut txn =
143 doc.transact_mut_with(doc.client_id().clone().to_string());
144 let context = crate::mapping::create_context(
146 "transaction_client".to_string(),
147 "transaction_user".to_string(),
148 );
149
150 let steps = &transaction.steps;
151 for step in steps {
152 if let Err(e) =
153 crate::mapping::convert_step(step.as_ref(), &mut txn, &context)
154 {
155 tracing::error!("🔄 应用步骤到 Yrs 事务失败: {}", e);
156 }
157 }
158 txn.commit();
160 tracing::debug!(
161 "🔄 应用 {} 个步骤到文档: {}",
162 transaction.steps.len(),
163 doc.client_id()
164 );
165
166 Ok(())
167 }
168
169 pub async fn apply_transactions_to_yrs(
171 awareness_ref: AwarenessRef,
172 transactions: &[Transaction],
173 ) -> ClientResult<()> {
174 let mut awareness = awareness_ref.write().await;
177 let doc = awareness.doc_mut();
178 let mut txn =
179 doc.transact_mut_with(doc.client_id().clone().to_string());
180
181 let context = crate::mapping::create_context(
183 "bulk_transaction_client".to_string(),
184 "bulk_transaction_user".to_string(),
185 );
186
187 for tr in transactions {
188 let steps = &tr.steps;
189 for step in steps {
190 if let Err(e) = crate::mapping::convert_step(
191 step.as_ref(),
192 &mut txn,
193 &context,
194 ) {
195 tracing::error!("🔄 应用步骤到 Yrs 事务失败: {}", e);
196 }
197 }
198 }
199 txn.commit();
201 tracing::debug!(
202 "🔄 应用 {} 个事务到文档: {}",
203 transactions.len(),
204 doc.client_id()
205 );
206
207 Ok(())
208 }
209
210 pub fn json_value_to_yrs_any(value: &JsonValue) -> yrs::Any {
213 match value {
214 JsonValue::Null => yrs::Any::Null,
215 JsonValue::Bool(b) => yrs::Any::Bool(*b),
216 JsonValue::Number(n) => {
217 if let Some(i) = n.as_i64() {
218 yrs::Any::BigInt(i)
219 } else if let Some(f) = n.as_f64() {
220 yrs::Any::Number(f)
221 } else {
222 yrs::Any::Null
223 }
224 },
225 JsonValue::String(s) => yrs::Any::String(s.clone().into()),
226 JsonValue::Array(arr) => {
227 let yrs_array: Vec<yrs::Any> =
228 arr.iter().map(Utils::json_value_to_yrs_any).collect();
229 yrs::Any::Array(yrs_array.into())
230 },
231 JsonValue::Object(obj) => {
232 let yrs_map: std::collections::HashMap<String, yrs::Any> = obj
233 .iter()
234 .map(|(k, v)| (k.clone(), Utils::json_value_to_yrs_any(v)))
235 .collect();
236 yrs::Any::Map(yrs_map.into())
237 },
238 }
239 }
240
241 pub fn add_mark_to_array(
243 marks_array: &ArrayRef,
244 txn: &mut TransactionMut,
245 mark: &Mark,
246 ) {
247 let mark_map = MapPrelim::<yrs::Any>::from([
248 ("type".to_string(), yrs::Any::String(mark.r#type.clone().into())),
249 ("attrs".to_string(), {
250 let attrs_map: std::collections::HashMap<String, yrs::Any> =
251 mark.attrs
252 .iter()
253 .map(|(k, v)| {
254 (k.clone(), Utils::json_value_to_yrs_any(v))
255 })
256 .collect();
257 yrs::Any::Map(attrs_map.into())
258 }),
259 ]);
260 marks_array.push_back(txn, mark_map);
261 }
262
263 pub fn get_or_create_node_data_map(
265 nodes_map: &MapRef,
266 txn: &mut TransactionMut,
267 node_id: &str,
268 ) -> MapRef {
269 if let Some(Value::YMap(map)) = nodes_map.get(txn, node_id) {
270 map
271 } else {
272 nodes_map.insert(
273 txn,
274 node_id.to_string(),
275 MapPrelim::<yrs::Any>::new(),
276 )
277 }
278 }
279
280 pub fn get_or_create_node_attrs_map(
282 node_data_map: &MapRef,
283 txn: &mut TransactionMut,
284 ) -> MapRef {
285 if let Some(Value::YMap(map)) = node_data_map.get(txn, "attrs") {
286 map
287 } else {
288 node_data_map.insert(txn, "attrs", MapPrelim::<yrs::Any>::new())
289 }
290 }
291
292 pub fn get_or_create_content_array(
294 node_data_map: &MapRef,
295 txn: &mut TransactionMut,
296 ) -> ArrayRef {
297 if let Some(Value::YArray(array)) = node_data_map.get(txn, "content") {
298 array
299 } else {
300 node_data_map.insert(
301 txn,
302 "content",
303 ArrayPrelim::from(Vec::<yrs::Any>::new()),
304 )
305 }
306 }
307
308 pub fn yrs_any_to_json_value(value: &yrs::Any) -> Option<JsonValue> {
310 match value {
311 yrs::Any::Null => Some(JsonValue::Null),
312 yrs::Any::Bool(b) => Some(JsonValue::Bool(*b)),
313 yrs::Any::Number(n) => {
314 Some(JsonValue::Number(serde_json::Number::from_f64(*n)?))
315 },
316 yrs::Any::BigInt(i) => {
317 Some(JsonValue::Number(serde_json::Number::from(*i)))
318 },
319 yrs::Any::String(s) => Some(JsonValue::String(s.to_string())),
320 yrs::Any::Array(arr) => {
321 let json_array: Vec<JsonValue> = arr
322 .iter()
323 .filter_map(Utils::yrs_any_to_json_value)
324 .collect();
325 Some(JsonValue::Array(json_array))
326 },
327 yrs::Any::Map(map) => {
328 let json_map: std::collections::HashMap<String, JsonValue> =
329 map.iter()
330 .filter_map(|(k, v)| {
331 Utils::yrs_any_to_json_value(v)
332 .map(|json_v| (k.to_string(), json_v))
333 })
334 .collect();
335 Some(JsonValue::Object(serde_json::Map::from_iter(json_map)))
336 },
337 _ => None, }
339 }
340
341 pub fn get_or_create_marks_array(
343 node_data_map: &MapRef,
344 txn: &mut TransactionMut,
345 ) -> ArrayRef {
346 if let Some(Value::YArray(array)) = node_data_map.get(txn, "marks") {
347 array
348 } else {
349 node_data_map.insert(
350 txn,
351 "marks",
352 ArrayPrelim::from(Vec::<yrs::Any>::new()),
353 )
354 }
355 }
356
357 pub fn get_root_id_from_yrs_doc(doc: &yrs::Doc) -> ClientResult<String> {
359 let txn = doc.transact();
360 if let Some(meta_map) = txn.get_map("meta") {
362 if let Some(yrs::types::Value::Any(any)) =
363 meta_map.get(&txn, "root_id")
364 {
365 return Ok(any.to_string());
366 }
367 }
368 let nodes_map = txn
370 .get_map("nodes")
371 .ok_or(anyhow::anyhow!("Yrs 文档中没有找到 nodes 映射"))?;
372 if let Some((key, _)) = nodes_map.iter(&txn).next() {
373 return Ok(key.to_string());
374 }
375 Err(anyhow::anyhow!("Yrs 文档中没有找到根节点"))
376 }
377
378 pub fn build_tree_nodes_from_yrs(
380 node_id: &str,
381 nodes_map: &yrs::types::map::MapRef,
382 txn: &yrs::Transaction,
383 tree_nodes: &mut HashMap<NodeId, Arc<Node>>,
384 parent_map: &mut HashMap<NodeId, NodeId>,
385 parent_id: Option<&NodeId>,
386 ) -> ClientResult<()> {
387 let node_data = nodes_map.get(txn, node_id);
388 if node_data.is_none() {
389 return Err(anyhow::anyhow!(
390 "节点 {} 在 Yrs 文档中不存在",
391 node_id
392 ));
393 }
394 let node_data = node_data.unwrap();
395 if let yrs::types::Value::YMap(node_map) = node_data {
396 let node_type = node_map
398 .get(txn, "type")
399 .and_then(|v| match v {
400 yrs::types::Value::Any(any) => Some(any.to_string()),
401 _ => None,
402 })
403 .unwrap_or_else(|| "unknown".to_string());
404
405 let mut attrs = Attrs::default();
407 if let Some(yrs::types::Value::YMap(attrs_yrs_map)) =
408 node_map.get(txn, "attrs")
409 {
410 for (key, value) in attrs_yrs_map.iter(txn) {
411 if let yrs::types::Value::Any(any_value) = value {
412 if let Some(json_value) =
413 Utils::yrs_any_to_json_value(&any_value)
414 {
415 attrs.insert_mut(key.to_string(), json_value);
416 }
417 }
418 }
419 }
420
421 let mut content = VectorSync::new_sync();
423 if let Some(yrs::types::Value::YArray(content_yrs_array)) =
424 node_map.get(txn, "content")
425 {
426 for item in content_yrs_array.iter(txn) {
427 if let yrs::types::Value::Any(any) = item {
428 content.push_back_mut(NodeId::from(any.to_string()));
429 }
430 }
431 }
432
433 let mut marks = VectorSync::new_sync();
435 if let Some(yrs::types::Value::YArray(marks_yrs_array)) =
436 node_map.get(txn, "marks")
437 {
438 for item in marks_yrs_array.iter(txn) {
439 if let yrs::types::Value::YMap(mark_map) = item {
440 let mark_type = mark_map
441 .get(txn, "type")
442 .and_then(|v| match v {
443 yrs::types::Value::Any(any) => {
444 Some(any.to_string())
445 },
446 _ => None,
447 })
448 .unwrap_or_else(|| "unknown".to_string());
449
450 let mut mark_attrs = Attrs::default();
451 if let Some(yrs::types::Value::YMap(attrs_yrs_map)) =
452 mark_map.get(txn, "attrs")
453 {
454 for (key, value) in attrs_yrs_map.iter(txn) {
455 if let yrs::types::Value::Any(any_value) = value
456 {
457 if let Some(json_value) =
458 Utils::yrs_any_to_json_value(&any_value)
459 {
460 mark_attrs.insert_mut(
461 key.to_string(),
462 json_value,
463 );
464 }
465 }
466 }
467 }
468
469 marks.push_back_mut(Mark {
470 r#type: mark_type,
471 attrs: mark_attrs,
472 });
473 }
474 }
475 }
476
477 let content_vec = content.clone();
479 let marks_vec = marks.clone();
480 let node = Node {
481 id: node_id.into(),
482 r#type: node_type,
483 attrs,
484 content: content_vec,
485 marks: marks_vec,
486 };
487 let node_id_typed = NodeId::from(node_id);
490 tree_nodes.insert(node_id_typed.clone(), Arc::new(node));
491
492 if let Some(parent) = parent_id {
494 parent_map.insert(node_id_typed.clone(), parent.clone());
495 }
496
497 for child_id in content.iter() {
499 Utils::build_tree_nodes_from_yrs(
500 &child_id,
501 nodes_map,
502 txn,
503 tree_nodes,
504 parent_map,
505 Some(&node_id_typed),
506 )?;
507 }
508 }
509 Ok(())
510 }
511
512 pub fn build_node_enum_from_map(
514 node: &Node,
515 tree_nodes: &HashMap<NodeId, Arc<Node>>,
516 ) -> mf_model::node_definition::NodeTree {
517 let mut children = Vec::new();
518 for child_id in &node.content {
519 if let Some(child_node) = tree_nodes.get(child_id) {
520 children.push(Utils::build_node_enum_from_map(
521 child_node, tree_nodes,
522 ));
523 }
524 }
525 mf_model::node_definition::NodeTree(node.clone(), children)
526 }
527}