jellyflow_runtime/runtime/store/
mod.rs1mod dispatch;
10mod dispatch_profile;
11mod events;
12mod history;
13mod snapshot;
14mod subscriptions;
15mod view;
16
17use std::cell::RefCell;
18
19use crate::io::{
20 NodeGraphEditorConfig, NodeGraphInteractionConfig, NodeGraphRuntimeTuning, NodeGraphViewState,
21};
22use crate::profile::{ApplyPipelineError, GraphProfile};
23use crate::runtime::commit::NodeGraphPatch;
24use crate::runtime::lookups::NodeGraphLookups;
25use crate::runtime::middleware::NodeGraphStoreMiddleware;
26use crate::runtime::query::spatial::SpatialQueryCache;
27use jellyflow_core::core::Graph;
28use jellyflow_core::ops::{GraphHistory, GraphTransaction};
29
30#[derive(Debug, Clone)]
32pub struct DispatchOutcome {
33 pub patch: NodeGraphPatch,
35}
36
37impl DispatchOutcome {
38 pub fn new(patch: NodeGraphPatch) -> Self {
39 Self { patch }
40 }
41
42 pub fn from_committed(committed: GraphTransaction) -> Self {
43 Self::new(NodeGraphPatch::new(committed))
44 }
45
46 pub fn committed(&self) -> &GraphTransaction {
47 self.patch.transaction()
48 }
49}
50
51#[derive(Debug, thiserror::Error)]
52pub enum DispatchError {
53 #[error(transparent)]
54 Apply(#[from] ApplyPipelineError),
55}
56
57pub struct NodeGraphStore {
61 graph: Graph,
62 graph_revision: u64,
63 layout_facts_revision: u64,
64 view_state: NodeGraphViewState,
65 interaction: NodeGraphInteractionConfig,
66 runtime_tuning: NodeGraphRuntimeTuning,
67 history: GraphHistory,
68 profile: Option<Box<dyn GraphProfile>>,
69 middleware: Option<Box<dyn NodeGraphStoreMiddleware>>,
70 lookups: NodeGraphLookups,
71 spatial_query_cache: RefCell<SpatialQueryCache>,
72 subscriptions: subscriptions::StoreSubscriptions,
73}
74
75impl std::fmt::Debug for NodeGraphStore {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 f.debug_struct("NodeGraphStore")
78 .field("graph_id", &self.graph.graph_id)
79 .field("graph_revision", &self.graph_revision)
80 .field("layout_facts_revision", &self.layout_facts_revision)
81 .field("node_count", &self.graph.nodes.len())
82 .field("edge_count", &self.graph.edges.len())
83 .field("lookup_node_count", &self.lookups.node_count())
84 .field("lookup_edge_count", &self.lookups.edge_count())
85 .field("undo_len", &self.history.undo_len())
86 .field("redo_len", &self.history.redo_len())
87 .field("has_profile", &self.profile.is_some())
88 .field(
89 "event_subscription_count",
90 &self.subscriptions.event_subscription_count(),
91 )
92 .field(
93 "gesture_subscription_count",
94 &self.subscriptions.gesture_subscription_count(),
95 )
96 .field(
97 "selector_subscription_count",
98 &self.subscriptions.selector_subscription_count(),
99 )
100 .finish()
101 }
102}
103
104impl NodeGraphStore {
105 pub fn new(
107 graph: Graph,
108 view_state: NodeGraphViewState,
109 editor_config: NodeGraphEditorConfig,
110 ) -> Self {
111 Self::new_with_optional_profile(graph, view_state, editor_config, None)
112 }
113
114 pub fn with_profile(
116 graph: Graph,
117 view_state: NodeGraphViewState,
118 editor_config: NodeGraphEditorConfig,
119 profile: Box<dyn GraphProfile>,
120 ) -> Self {
121 Self::new_with_optional_profile(graph, view_state, editor_config, Some(profile))
122 }
123
124 fn new_with_optional_profile(
125 graph: Graph,
126 mut view_state: NodeGraphViewState,
127 editor_config: NodeGraphEditorConfig,
128 profile: Option<Box<dyn GraphProfile>>,
129 ) -> Self {
130 view_state.sanitize_for_graph(&graph);
131 let mut lookups = NodeGraphLookups::default();
132 lookups.rebuild_from(&graph);
133 let (interaction, runtime_tuning) = editor_config.into_parts();
134 Self {
135 graph,
136 graph_revision: 0,
137 layout_facts_revision: 0,
138 view_state,
139 interaction,
140 runtime_tuning,
141 history: GraphHistory::default(),
142 profile,
143 middleware: None,
144 lookups,
145 spatial_query_cache: RefCell::new(SpatialQueryCache::default()),
146 subscriptions: subscriptions::StoreSubscriptions::default(),
147 }
148 }
149
150 pub(crate) fn spatial_query_cache(&self) -> &RefCell<SpatialQueryCache> {
151 &self.spatial_query_cache
152 }
153
154 pub fn with_middleware(mut self, middleware: impl NodeGraphStoreMiddleware) -> Self {
155 self.middleware = Some(Box::new(middleware));
156 self
157 }
158}