moduforge_runtime/
runtime.rs1use std::sync::Arc;
2
3use crate::{
4 error::{EditorError, EditorResult, error_utils},
5 event::{Event, EventBus},
6 extension_manager::ExtensionManager,
7 helpers::create_doc,
8 history_manager::HistoryManager,
9 types::EditorOptions,
10 traits::{EditorCore, EditorBase},
11};
12use async_trait::async_trait;
13use moduforge_core::{
14 model::{node_pool::NodePool, schema::Schema},
15 state::{
16 state::{State, StateConfig, TransactionResult},
17 transaction::{Command, Transaction},
18 },
19 transform::transform::Transform,
20};
21
22pub struct Editor {
25 base: EditorBase,
26}
27
28impl Editor {
29 pub async fn create(options: EditorOptions) -> EditorResult<Self> {
32 let extension_manager = ExtensionManager::new(&options.get_extensions());
33
34 let doc = create_doc::create_doc(&options.get_content());
35 let event_bus = EventBus::new();
36
37 let state: State = State::create(StateConfig {
38 schema: Some(extension_manager.get_schema()),
39 doc,
40 stored_marks: None,
41 plugins: Some(extension_manager.get_plugins().clone()),
42 })
43 .await
44 .map_err(|e| error_utils::state_error(format!("Failed to create state: {}", e)))?;
45
46 let state: Arc<State> = Arc::new(state);
47
48 let base = EditorBase {
49 event_bus,
50 state: state.clone(),
51 extension_manager,
52 history_manager: HistoryManager::new(state, options.get_history_limit()),
53 options,
54 };
55
56 let mut runtime = Editor { base };
57 runtime.init().await?;
58 Ok(runtime)
59 }
60
61 async fn init(&mut self) -> EditorResult<()> {
63 self.base.event_bus.add_event_handlers(self.base.options.get_event_handlers()).await?;
64 self.base.event_bus.start_event_loop();
65 self.base
66 .event_bus
67 .broadcast_blocking(Event::Create(self.base.state.clone()))
68 .map_err(|e| error_utils::event_error(format!("Failed to broadcast create event: {}", e)))?;
69 Ok(())
70 }
71}
72#[async_trait]
73impl EditorCore for Editor {
74 type Error = EditorError;
75
76 fn doc(&self) -> Arc<NodePool> {
77 self.base.doc()
78 }
79
80 fn get_options(&self) -> &EditorOptions {
81 self.base.get_options()
82 }
83
84 fn get_state(&self) -> &Arc<State> {
85 self.base.get_state()
86 }
87
88 fn get_schema(&self) -> Arc<Schema> {
89 self.base.get_schema()
90 }
91
92 fn get_event_bus(&self) -> &EventBus {
93 self.base.get_event_bus()
94 }
95
96 fn get_tr(&self) -> Transaction {
97 self.base.get_tr()
98 }
99
100 async fn command(
101 &mut self,
102 command: Arc<dyn Command>,
103 ) -> EditorResult<()> {
104 let mut tr = self.get_tr();
105 tr.transaction(command).await;
106 self.dispatch(tr).await
107 }
108
109 async fn dispatch(
110 &mut self,
111 transaction: Transaction,
112 ) -> EditorResult<()> {
113 let TransactionResult { state, mut trs } = self
114 .base
115 .state
116 .apply(transaction)
117 .await
118 .map_err(|e| error_utils::state_error(format!("Failed to apply transaction: {}", e)))?;
119 let tr = trs.pop().unwrap();
120 if !tr.doc_changed() {
121 return Ok(());
122 }
123 self.base.state = Arc::new(state);
124 self.base.history_manager.insert(self.base.state.clone());
125 let event_bus = self.get_event_bus();
126
127 event_bus
128 .broadcast(Event::TrApply(Arc::new(tr), self.base.state.clone()))
129 .await
130 .map_err(|e| error_utils::event_error(format!("Failed to broadcast transaction event: {}", e)))?;
131 Ok(())
132 }
133
134 async fn register_plugin(&mut self) -> EditorResult<()> {
135 let state = self
136 .get_state()
137 .reconfigure(StateConfig {
138 schema: Some(self.get_schema()),
139 doc: Some(self.get_state().doc()),
140 stored_marks: None,
141 plugins: Some(self.get_state().plugins().clone()),
142 })
143 .await
144 .map_err(|e| error_utils::state_error(format!("Failed to reconfigure state: {}", e)))?;
145 self.base.state = Arc::new(state);
146 Ok(())
147 }
148
149 async fn unregister_plugin(
150 &mut self,
151 plugin_key: String,
152 ) -> EditorResult<()> {
153 let ps = self.get_state().plugins().iter().filter(|p| p.key != plugin_key).cloned().collect();
154 let state = self
155 .get_state()
156 .reconfigure(StateConfig {
157 schema: Some(self.get_schema().clone()),
158 doc: Some(self.get_state().doc()),
159 stored_marks: None,
160 plugins: Some(ps),
161 })
162 .await
163 .map_err(|e| error_utils::state_error(format!("Failed to reconfigure state: {}", e)))?;
164 self.base.state = Arc::new(state);
165 Ok(())
166 }
167
168 fn undo(&mut self) {
169 self.base.undo()
170 }
171
172 fn redo(&mut self) {
173 self.base.redo()
174 }
175}