Skip to main content

jellyflow_core/ops/transaction/
op.rs

1use serde::{Deserialize, Serialize};
2
3use crate::core::{
4    Binding, BindingEndpoint, BindingId, CanvasPoint, CanvasRect, CanvasSize, Edge, EdgeId,
5    EdgeKind, EdgeReconnectable, GraphId, GraphImport, Group, GroupId, Node, NodeExtent, NodeId,
6    NodeKindKey, NodeOrigin, Port, PortId, StickyNote, StickyNoteId, Symbol, SymbolId,
7};
8use crate::types::TypeDesc;
9
10use super::endpoints::EdgeEndpoints;
11
12/// A reversible edit operation.
13///
14/// Destructive variants carry the removed data so the operation can be inverted for undo/redo.
15/// Higher-level tools should batch multiple ops into a single transaction.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(tag = "op", rename_all = "snake_case")]
18pub enum GraphOp {
19    /// Adds a node.
20    AddNode { id: NodeId, node: Node },
21    /// Removes a node.
22    ///
23    /// This operation is expected to remove associated ports and edges as well.
24    RemoveNode {
25        id: NodeId,
26        node: Node,
27        #[serde(default, skip_serializing_if = "Vec::is_empty")]
28        ports: Vec<(PortId, Port)>,
29        #[serde(default, skip_serializing_if = "Vec::is_empty")]
30        edges: Vec<(EdgeId, Edge)>,
31        #[serde(default, skip_serializing_if = "Vec::is_empty")]
32        bindings: Vec<(BindingId, Binding)>,
33    },
34    /// Sets a node position.
35    SetNodePos {
36        id: NodeId,
37        from: CanvasPoint,
38        to: CanvasPoint,
39    },
40    /// Sets a node origin override.
41    SetNodeOrigin {
42        id: NodeId,
43        from: Option<NodeOrigin>,
44        to: Option<NodeOrigin>,
45    },
46    /// Sets a node kind identifier.
47    SetNodeKind {
48        id: NodeId,
49        from: NodeKindKey,
50        to: NodeKindKey,
51    },
52    /// Sets a node kind version (for per-kind migrations).
53    SetNodeKindVersion { id: NodeId, from: u32, to: u32 },
54    /// Sets a node selectable override.
55    SetNodeSelectable {
56        id: NodeId,
57        from: Option<bool>,
58        to: Option<bool>,
59    },
60    /// Sets a node focusable override.
61    SetNodeFocusable {
62        id: NodeId,
63        from: Option<bool>,
64        to: Option<bool>,
65    },
66    /// Sets a node draggable override.
67    SetNodeDraggable {
68        id: NodeId,
69        from: Option<bool>,
70        to: Option<bool>,
71    },
72    /// Sets a node connectable override.
73    SetNodeConnectable {
74        id: NodeId,
75        from: Option<bool>,
76        to: Option<bool>,
77    },
78    /// Sets a node deletable override.
79    SetNodeDeletable {
80        id: NodeId,
81        from: Option<bool>,
82        to: Option<bool>,
83    },
84    /// Sets a node parent container (group frame).
85    SetNodeParent {
86        id: NodeId,
87        from: Option<GroupId>,
88        to: Option<GroupId>,
89    },
90    /// Sets a node extent override.
91    SetNodeExtent {
92        id: NodeId,
93        from: Option<NodeExtent>,
94        to: Option<NodeExtent>,
95    },
96    /// Sets a node expand-parent override.
97    SetNodeExpandParent {
98        id: NodeId,
99        from: Option<bool>,
100        to: Option<bool>,
101    },
102    /// Sets a node explicit size.
103    SetNodeSize {
104        id: NodeId,
105        from: Option<CanvasSize>,
106        to: Option<CanvasSize>,
107    },
108    /// Sets a node hidden state.
109    SetNodeHidden { id: NodeId, from: bool, to: bool },
110    /// Sets a node collapsed state.
111    SetNodeCollapsed { id: NodeId, from: bool, to: bool },
112    /// Sets a node's port ordering.
113    SetNodePorts {
114        id: NodeId,
115        from: Vec<PortId>,
116        to: Vec<PortId>,
117    },
118    /// Sets a node's domain-owned data payload.
119    ///
120    /// This is the primary edit op for node parameters and is intentionally untyped at the model
121    /// layer: typing and validation live in profiles/rules.
122    SetNodeData {
123        id: NodeId,
124        from: serde_json::Value,
125        to: serde_json::Value,
126    },
127
128    /// Adds a port.
129    AddPort { id: PortId, port: Port },
130    /// Removes a port.
131    ///
132    /// This operation is expected to remove associated edges as well.
133    RemovePort {
134        id: PortId,
135        port: Port,
136        #[serde(default, skip_serializing_if = "Vec::is_empty")]
137        edges: Vec<(EdgeId, Edge)>,
138        #[serde(default, skip_serializing_if = "Vec::is_empty")]
139        bindings: Vec<(BindingId, Binding)>,
140    },
141    /// Sets a port connectable override.
142    SetPortConnectable {
143        id: PortId,
144        from: Option<bool>,
145        to: Option<bool>,
146    },
147    /// Sets a port start-connectable override.
148    SetPortConnectableStart {
149        id: PortId,
150        from: Option<bool>,
151        to: Option<bool>,
152    },
153    /// Sets a port end-connectable override.
154    SetPortConnectableEnd {
155        id: PortId,
156        from: Option<bool>,
157        to: Option<bool>,
158    },
159    /// Sets a port type descriptor.
160    SetPortType {
161        id: PortId,
162        from: Option<TypeDesc>,
163        to: Option<TypeDesc>,
164    },
165    /// Sets a port domain-owned data payload.
166    SetPortData {
167        id: PortId,
168        from: serde_json::Value,
169        to: serde_json::Value,
170    },
171
172    /// Adds an edge.
173    AddEdge { id: EdgeId, edge: Edge },
174    /// Removes an edge.
175    RemoveEdge {
176        id: EdgeId,
177        edge: Edge,
178        #[serde(default, skip_serializing_if = "Vec::is_empty")]
179        bindings: Vec<(BindingId, Binding)>,
180    },
181    /// Sets an edge kind.
182    SetEdgeKind {
183        id: EdgeId,
184        from: EdgeKind,
185        to: EdgeKind,
186    },
187    /// Sets an edge selectable override.
188    SetEdgeSelectable {
189        id: EdgeId,
190        from: Option<bool>,
191        to: Option<bool>,
192    },
193    /// Sets an edge focusable override.
194    SetEdgeFocusable {
195        id: EdgeId,
196        from: Option<bool>,
197        to: Option<bool>,
198    },
199    /// Sets an edge hidden flag.
200    SetEdgeHidden { id: EdgeId, from: bool, to: bool },
201    /// Sets an edge hit-test interaction width override.
202    SetEdgeInteractionWidth {
203        id: EdgeId,
204        from: Option<f32>,
205        to: Option<f32>,
206    },
207    /// Sets an edge deletable override.
208    SetEdgeDeletable {
209        id: EdgeId,
210        from: Option<bool>,
211        to: Option<bool>,
212    },
213    /// Sets an edge reconnectable override.
214    SetEdgeReconnectable {
215        id: EdgeId,
216        from: Option<EdgeReconnectable>,
217        to: Option<EdgeReconnectable>,
218    },
219    /// Sets an edge's endpoints (preserving edge identity for reconnection workflows).
220    SetEdgeEndpoints {
221        id: EdgeId,
222        from: EdgeEndpoints,
223        to: EdgeEndpoints,
224    },
225
226    /// Adds a graph import reference.
227    AddImport { id: GraphId, import: GraphImport },
228    /// Removes a graph import reference.
229    RemoveImport { id: GraphId, import: GraphImport },
230    /// Sets an import alias.
231    SetImportAlias {
232        id: GraphId,
233        from: Option<String>,
234        to: Option<String>,
235    },
236
237    /// Adds a symbol.
238    AddSymbol { id: SymbolId, symbol: Symbol },
239    /// Removes a symbol.
240    RemoveSymbol { id: SymbolId, symbol: Symbol },
241    /// Sets a symbol name.
242    SetSymbolName {
243        id: SymbolId,
244        from: String,
245        to: String,
246    },
247    /// Sets a symbol type descriptor.
248    SetSymbolType {
249        id: SymbolId,
250        from: Option<TypeDesc>,
251        to: Option<TypeDesc>,
252    },
253    /// Sets a symbol default value.
254    SetSymbolDefaultValue {
255        id: SymbolId,
256        from: Option<serde_json::Value>,
257        to: Option<serde_json::Value>,
258    },
259    /// Updates a symbol metadata payload (domain-owned).
260    SetSymbolMeta {
261        id: SymbolId,
262        from: serde_json::Value,
263        to: serde_json::Value,
264    },
265
266    /// Adds a group.
267    AddGroup { id: GroupId, group: Group },
268    /// Removes a group.
269    ///
270    /// This operation is expected to detach nodes that were parented to the group.
271    RemoveGroup {
272        id: GroupId,
273        group: Group,
274        #[serde(default, skip_serializing_if = "Vec::is_empty")]
275        detached: Vec<(NodeId, Option<GroupId>)>,
276        #[serde(default, skip_serializing_if = "Vec::is_empty")]
277        bindings: Vec<(BindingId, Binding)>,
278    },
279    /// Sets a group's bounds.
280    SetGroupRect {
281        id: GroupId,
282        from: CanvasRect,
283        to: CanvasRect,
284    },
285    /// Sets a group's title.
286    SetGroupTitle {
287        id: GroupId,
288        from: String,
289        to: String,
290    },
291    /// Sets a group color override.
292    SetGroupColor {
293        id: GroupId,
294        from: Option<String>,
295        to: Option<String>,
296    },
297
298    /// Adds a sticky note.
299    AddStickyNote { id: StickyNoteId, note: StickyNote },
300    /// Removes a sticky note.
301    RemoveStickyNote {
302        id: StickyNoteId,
303        note: StickyNote,
304        #[serde(default, skip_serializing_if = "Vec::is_empty")]
305        bindings: Vec<(BindingId, Binding)>,
306    },
307    /// Sets a sticky note text body.
308    SetStickyNoteText {
309        id: StickyNoteId,
310        from: String,
311        to: String,
312    },
313    /// Sets a sticky note bounds.
314    SetStickyNoteRect {
315        id: StickyNoteId,
316        from: CanvasRect,
317        to: CanvasRect,
318    },
319    /// Sets a sticky note color override.
320    SetStickyNoteColor {
321        id: StickyNoteId,
322        from: Option<String>,
323        to: Option<String>,
324    },
325
326    /// Adds a knowledge-canvas binding.
327    AddBinding { id: BindingId, binding: Binding },
328    /// Removes a knowledge-canvas binding.
329    RemoveBinding { id: BindingId, binding: Binding },
330    /// Sets a binding subject endpoint.
331    SetBindingSubject {
332        id: BindingId,
333        from: BindingEndpoint,
334        to: BindingEndpoint,
335    },
336    /// Sets a binding target endpoint.
337    SetBindingTarget {
338        id: BindingId,
339        from: BindingEndpoint,
340        to: BindingEndpoint,
341    },
342    /// Sets a binding relationship label.
343    SetBindingKind {
344        id: BindingId,
345        from: Option<String>,
346        to: Option<String>,
347    },
348    /// Updates a binding metadata payload (domain-owned).
349    SetBindingMeta {
350        id: BindingId,
351        from: serde_json::Value,
352        to: serde_json::Value,
353    },
354}