1use std::time::{SystemTime, UNIX_EPOCH};
2use mf_model::mark::Mark;
3use mf_model::node_type::NodeEnum;
4use mf_model::tree::Tree;
5use mf_state::Transaction;
6use crate::mapping::{NodeStepConverter, StepConverter};
7use crate::AwarenessRef;
8use serde_json::Value as JsonValue;
9use yrs::{Map, ReadTxn, Transact};
10use yrs::{
11 types::{array::ArrayRef, map::MapRef, Value},
12 Array, ArrayPrelim, MapPrelim, TransactionMut, WriteTxn,
13};
14
15use crate::{mapping::Mapper, ClientResult};
16use mf_model::{node::Node, attrs::Attrs, types::NodeId};
17use std::sync::Arc;
18use std::collections::HashMap;
19
20pub fn get_unix_time() -> u64 {
22 SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or_default().as_millis()
23 as u64
24}
25
26pub struct Utils;
27impl Utils {
28
29 pub fn apply_yrs_to_tree(
32 doc: &yrs::Doc
33 ) -> Result<Tree, Box<dyn std::error::Error>> {
34 use mf_model::types::NodeId;
35 use std::collections::HashMap;
36
37 let root_id = Utils::get_root_id_from_yrs_doc(doc)?;
38 let txn = doc.transact();
39 let nodes_map =
40 txn.get_map("nodes").ok_or("Yrs 文档中没有找到 nodes 映射")?;
41 let mut tree_nodes = HashMap::new();
42 let mut parent_map = HashMap::new();
43
44 Utils::build_tree_nodes_from_yrs(
45 &root_id,
46 &nodes_map,
47 &txn,
48 &mut tree_nodes,
49 &mut parent_map,
50 None,
51 )?;
52
53 let root_node = tree_nodes
54 .get(&NodeId::from(root_id))
55 .ok_or("根节点不存在")?
56 .as_ref()
57 .clone();
58 let root_enum =
59 Utils::build_node_enum_from_map(&root_node, &tree_nodes);
60 Ok(Tree::from(root_enum))
61 }
62 pub async fn apply_tree_to_yrs(
65 awareness_ref: AwarenessRef,
66 tree: &Tree,
67 ) -> ClientResult<()> {
68 let mut awareness = awareness_ref.write().await;
69 let doc = awareness.doc_mut();
70 let mut txn = doc.transact_mut_with(doc.client_id().clone());
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.len(),
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::{step::Step, node_step::AddNodeStep};
104
105 let root_node = tree.get_node(&tree.root_id).unwrap();
106 if let Some(root_tree) = tree.all_children(&tree.root_id, None) {
108 let add_step = AddNodeStep {
110 parent_id: tree.root_id.clone(),
111 nodes: vec![NodeEnum(
112 root_node.as_ref().clone(),
113 vec![root_tree],
114 )],
115 };
116 let node_step_converter = NodeStepConverter;
117 if let Err(e) = node_step_converter
118 .apply_to_yrs_txn(&add_step as &dyn Step, txn)
119 {
120 tracing::error!("🔄 同步树节点到 Yrs 失败: {}", e);
121 return Err(anyhow::anyhow!(format!(
122 "Failed to sync tree: {}",
123 e
124 ),));
125 }
126 }
127
128 Ok(())
129 }
130
131 pub async fn apply_transaction_to_yrs(
133 awareness_ref: AwarenessRef,
134 transaction: &Transaction,
135 ) -> ClientResult<()> {
136 let mut awareness = awareness_ref.write().await;
139 let doc = awareness.doc_mut();
140 let mut txn = doc.transact_mut_with(doc.client_id().clone());
141
142 let registry = Mapper::global_registry();
144
145
146 let steps = &transaction.steps;
147 for step in steps {
148 if let Some(converter) = registry.find_converter(step.as_ref())
149 {
150 if let Err(e) =
151 converter.apply_to_yrs_txn(step.as_ref(), &mut txn)
152 {
153 tracing::error!("🔄 应用步骤到 Yrs 事务失败: {}", e);
154 }
155 } else {
156 let type_name = std::any::type_name_of_val(step.as_ref());
157 tracing::warn!(
158 "🔄 应用步骤到 Yrs 事务失败: 没有找到步骤的转换器: {}",
159 type_name
160 );
161 }
162 }
163
164 txn.commit();
166 tracing::debug!(
167 "🔄 应用 {} 个步骤到文档: {}",
168 transaction.steps.len(),
169 doc.client_id()
170 );
171
172 Ok(())
173 }
174
175 pub async fn apply_transactions_to_yrs(
177 awareness_ref: AwarenessRef,
178 transactions: &[Transaction],
179 ) -> ClientResult<()> {
180 let mut awareness = awareness_ref.write().await;
183 let doc = awareness.doc_mut();
184 let mut txn = doc.transact_mut_with(doc.client_id().clone());
185
186 let registry = Mapper::global_registry();
188
189 for tr in transactions {
190 let steps = &tr.steps;
191 for step in steps {
192 if let Some(converter) = registry.find_converter(step.as_ref())
193 {
194 if let Err(e) =
195 converter.apply_to_yrs_txn(step.as_ref(), &mut txn)
196 {
197 tracing::error!("🔄 应用步骤到 Yrs 事务失败: {}", e);
198 }
199 } else {
200 let type_name = std::any::type_name_of_val(step.as_ref());
201 tracing::warn!(
202 "🔄 应用步骤到 Yrs 事务失败: 没有找到步骤的转换器: {}",
203 type_name
204 );
205 }
206 }
207 }
208 txn.commit();
210 tracing::debug!(
211 "🔄 应用 {} 个事务到文档: {}",
212 transactions.len(),
213 doc.client_id()
214 );
215
216 Ok(())
217 }
218
219 pub fn json_value_to_yrs_any(value: &JsonValue) -> yrs::Any {
222 match value {
223 JsonValue::Null => yrs::Any::Null,
224 JsonValue::Bool(b) => yrs::Any::Bool(*b),
225 JsonValue::Number(n) => {
226 if let Some(i) = n.as_i64() {
227 yrs::Any::BigInt(i)
228 } else if let Some(f) = n.as_f64() {
229 yrs::Any::Number(f)
230 } else {
231 yrs::Any::Null
232 }
233 },
234 JsonValue::String(s) => yrs::Any::String(s.clone().into()),
235 JsonValue::Array(arr) => {
236 let yrs_array: Vec<yrs::Any> =
237 arr.iter().map(Utils::json_value_to_yrs_any).collect();
238 yrs::Any::Array(yrs_array.into())
239 },
240 JsonValue::Object(obj) => {
241 let yrs_map: std::collections::HashMap<String, yrs::Any> = obj
242 .iter()
243 .map(|(k, v)| (k.clone(), Utils::json_value_to_yrs_any(v)))
244 .collect();
245 yrs::Any::Map(yrs_map.into())
246 },
247 }
248 }
249
250 pub fn add_mark_to_array(
252 marks_array: &ArrayRef,
253 txn: &mut TransactionMut,
254 mark: &Mark,
255 ) {
256 let mark_map = MapPrelim::<yrs::Any>::from([
257 ("type".to_string(), yrs::Any::String(mark.r#type.clone().into())),
258 ("attrs".to_string(), {
259 let attrs_map: std::collections::HashMap<String, yrs::Any> =
260 mark.attrs
261 .iter()
262 .map(|(k, v)| {
263 (k.clone(), Utils::json_value_to_yrs_any(v))
264 })
265 .collect();
266 yrs::Any::Map(attrs_map.into())
267 }),
268 ]);
269 marks_array.push_back(txn, mark_map);
270 }
271
272 pub fn get_or_create_node_data_map(
274 nodes_map: &MapRef,
275 txn: &mut TransactionMut,
276 node_id: &str,
277 ) -> MapRef {
278 if let Some(Value::YMap(map)) = nodes_map.get(txn, node_id) {
279 map
280 } else {
281 nodes_map.insert(
282 txn,
283 node_id.to_string(),
284 MapPrelim::<yrs::Any>::new(),
285 )
286 }
287 }
288
289 pub fn get_or_create_node_attrs_map(
291 node_data_map: &MapRef,
292 txn: &mut TransactionMut,
293 ) -> MapRef {
294 if let Some(Value::YMap(map)) = node_data_map.get(txn, "attrs") {
295 map
296 } else {
297 node_data_map.insert(txn, "attrs", MapPrelim::<yrs::Any>::new())
298 }
299 }
300
301 pub fn get_or_create_content_array(
303 node_data_map: &MapRef,
304 txn: &mut TransactionMut,
305 ) -> ArrayRef {
306 if let Some(Value::YArray(array)) = node_data_map.get(txn, "content") {
307 array
308 } else {
309 node_data_map.insert(
310 txn,
311 "content",
312 ArrayPrelim::from(Vec::<yrs::Any>::new()),
313 )
314 }
315 }
316
317 pub fn yrs_any_to_json_value(value: &yrs::Any) -> Option<JsonValue> {
319 match value {
320 yrs::Any::Null => Some(JsonValue::Null),
321 yrs::Any::Bool(b) => Some(JsonValue::Bool(*b)),
322 yrs::Any::Number(n) => {
323 Some(JsonValue::Number(serde_json::Number::from_f64(*n)?))
324 },
325 yrs::Any::BigInt(i) => {
326 Some(JsonValue::Number(serde_json::Number::from(*i)))
327 },
328 yrs::Any::String(s) => Some(JsonValue::String(s.to_string())),
329 yrs::Any::Array(arr) => {
330 let json_array: Vec<JsonValue> = arr
331 .iter()
332 .filter_map(Utils::yrs_any_to_json_value)
333 .collect();
334 Some(JsonValue::Array(json_array))
335 },
336 yrs::Any::Map(map) => {
337 let json_map: std::collections::HashMap<String, JsonValue> =
338 map.iter()
339 .filter_map(|(k, v)| {
340 Utils::yrs_any_to_json_value(v)
341 .map(|json_v| (k.to_string(), json_v))
342 })
343 .collect();
344 Some(JsonValue::Object(serde_json::Map::from_iter(json_map)))
345 },
346 _ => None, }
348 }
349
350 pub fn get_or_create_marks_array(
352 node_data_map: &MapRef,
353 txn: &mut TransactionMut,
354 ) -> ArrayRef {
355 if let Some(Value::YArray(array)) = node_data_map.get(txn, "marks") {
356 array
357 } else {
358 node_data_map.insert(
359 txn,
360 "marks",
361 ArrayPrelim::from(Vec::<yrs::Any>::new()),
362 )
363 }
364 }
365
366 pub fn get_root_id_from_yrs_doc(
368 doc: &yrs::Doc
369 ) -> Result<String, Box<dyn std::error::Error>> {
370 let txn = doc.transact();
371 if let Some(meta_map) = txn.get_map("meta") {
373 if let Some(yrs::types::Value::Any(any)) =
374 meta_map.get(&txn, "root_id")
375 {
376 return Ok(any.to_string());
377 }
378 }
379 let nodes_map =
381 txn.get_map("nodes").ok_or("Yrs 文档中没有找到 nodes 映射")?;
382 for (key, _) in nodes_map.iter(&txn) {
383 return Ok(key.to_string());
384 }
385 Err("Yrs 文档中没有找到根节点".into())
386 }
387
388 pub fn build_tree_nodes_from_yrs(
390 node_id: &str,
391 nodes_map: &yrs::types::map::MapRef,
392 txn: &yrs::Transaction,
393 tree_nodes: &mut HashMap<NodeId, Arc<Node>>,
394 parent_map: &mut HashMap<NodeId, NodeId>,
395 parent_id: Option<&NodeId>,
396 ) -> Result<(), Box<dyn std::error::Error>> {
397 let node_data = nodes_map.get(txn, node_id);
398 if node_data.is_none() {
399 return Err(format!("节点 {} 在 Yrs 文档中不存在", node_id).into());
400 }
401 let node_data = node_data.unwrap();
402 if let yrs::types::Value::YMap(node_map) = node_data {
403 let node_type = node_map
405 .get(txn, "type")
406 .and_then(|v| match v {
407 yrs::types::Value::Any(any) => Some(any.to_string()),
408 _ => None,
409 })
410 .unwrap_or_else(|| "unknown".to_string());
411
412 let mut attrs = Attrs::default();
414 if let Some(attrs_map) = node_map.get(txn, "attrs") {
415 if let yrs::types::Value::YMap(attrs_yrs_map) = attrs_map {
416 for (key, value) in attrs_yrs_map.iter(txn) {
417 if let yrs::types::Value::Any(any_value) = value {
418 if let Some(json_value) =
419 Utils::yrs_any_to_json_value(&any_value)
420 {
421 attrs.insert(key.to_string(), json_value);
422 }
423 }
424 }
425 }
426 }
427
428 let mut content = im::Vector::new();
430 if let Some(content_array) = node_map.get(txn, "content") {
431 if let yrs::types::Value::YArray(content_yrs_array) =
432 content_array
433 {
434 for item in content_yrs_array.iter(txn) {
435 if let yrs::types::Value::Any(any) = item {
436 content.push_back(NodeId::from(any.to_string()));
437 }
438 }
439 }
440 }
441
442 let mut marks = im::Vector::new();
444 if let Some(marks_array) = node_map.get(txn, "marks") {
445 if let yrs::types::Value::YArray(marks_yrs_array) = marks_array
446 {
447 for item in marks_yrs_array.iter(txn) {
448 if let yrs::types::Value::YMap(mark_map) = item {
449 let mark_type = mark_map
450 .get(txn, "type")
451 .and_then(|v| match v {
452 yrs::types::Value::Any(any) => {
453 Some(any.to_string())
454 },
455 _ => None,
456 })
457 .unwrap_or_else(|| "unknown".to_string());
458
459 let mut mark_attrs = Attrs::default();
460 if let Some(mark_attrs_map) =
461 mark_map.get(txn, "attrs")
462 {
463 if let yrs::types::Value::YMap(attrs_yrs_map) =
464 mark_attrs_map
465 {
466 for (key, value) in attrs_yrs_map.iter(txn)
467 {
468 if let yrs::types::Value::Any(
469 any_value,
470 ) = value
471 {
472 if let Some(json_value) =
473 Utils::yrs_any_to_json_value(
474 &any_value,
475 )
476 {
477 mark_attrs.insert(
478 key.to_string(),
479 json_value,
480 );
481 }
482 }
483 }
484 }
485 }
486
487 marks.push_back(Mark {
488 r#type: mark_type,
489 attrs: mark_attrs,
490 });
491 }
492 }
493 }
494 }
495
496 let content_vec: Vec<String> =
498 content.clone().into_iter().collect();
499 let marks_vec: Vec<Mark> = marks.clone().into_iter().collect();
500 let node =
501 Node::new(node_id, node_type, attrs, content_vec, marks_vec);
502
503 let node_id_typed = NodeId::from(node_id);
504 tree_nodes.insert(node_id_typed.clone(), Arc::new(node));
505
506 if let Some(parent) = parent_id {
508 parent_map.insert(node_id_typed.clone(), parent.clone());
509 }
510
511 for child_id in content {
513 Utils::build_tree_nodes_from_yrs(
514 &child_id,
515 nodes_map,
516 txn,
517 tree_nodes,
518 parent_map,
519 Some(&node_id_typed),
520 )?;
521 }
522 }
523 Ok(())
524 }
525
526 pub fn build_node_enum_from_map(
528 node: &Node,
529 tree_nodes: &HashMap<NodeId, Arc<Node>>,
530 ) -> mf_model::node_type::NodeEnum {
531 let mut children = Vec::new();
532 for child_id in &node.content {
533 if let Some(child_node) = tree_nodes.get(child_id) {
534 children.push(Utils::build_node_enum_from_map(
535 child_node, tree_nodes,
536 ));
537 }
538 }
539 mf_model::node_type::NodeEnum(node.clone(), children)
540 }
541}