@coral-viz/viz 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +11 -0
  3. package/dist/compatibility/CompatibilityEdge.d.ts +106 -0
  4. package/dist/compatibility/CompatibilityEdge.d.ts.map +1 -0
  5. package/dist/compatibility/CompatibilityEdge.js +233 -0
  6. package/dist/compatibility/CompatibilityEdge.js.map +1 -0
  7. package/dist/compatibility/IncompatibilityTooltip.d.ts +44 -0
  8. package/dist/compatibility/IncompatibilityTooltip.d.ts.map +1 -0
  9. package/dist/compatibility/IncompatibilityTooltip.js +145 -0
  10. package/dist/compatibility/IncompatibilityTooltip.js.map +1 -0
  11. package/dist/compatibility/index.d.ts +10 -0
  12. package/dist/compatibility/index.d.ts.map +1 -0
  13. package/dist/compatibility/index.js +10 -0
  14. package/dist/compatibility/index.js.map +1 -0
  15. package/dist/compatibility/useEdgeCompatibility.d.ts +82 -0
  16. package/dist/compatibility/useEdgeCompatibility.d.ts.map +1 -0
  17. package/dist/compatibility/useEdgeCompatibility.js +170 -0
  18. package/dist/compatibility/useEdgeCompatibility.js.map +1 -0
  19. package/dist/compatibility/validateConnection.d.ts +56 -0
  20. package/dist/compatibility/validateConnection.d.ts.map +1 -0
  21. package/dist/compatibility/validateConnection.js +382 -0
  22. package/dist/compatibility/validateConnection.js.map +1 -0
  23. package/dist/components/EditContext.d.ts +45 -0
  24. package/dist/components/EditContext.d.ts.map +1 -0
  25. package/dist/components/EditContext.js +41 -0
  26. package/dist/components/EditContext.js.map +1 -0
  27. package/dist/components/ShapeRenderer.d.ts +35 -0
  28. package/dist/components/ShapeRenderer.d.ts.map +1 -0
  29. package/dist/components/ShapeRenderer.js +77 -0
  30. package/dist/components/ShapeRenderer.js.map +1 -0
  31. package/dist/components/SymbolNode.d.ts +53 -0
  32. package/dist/components/SymbolNode.d.ts.map +1 -0
  33. package/dist/components/SymbolNode.js +333 -0
  34. package/dist/components/SymbolNode.js.map +1 -0
  35. package/dist/components/index.d.ts +8 -0
  36. package/dist/components/index.d.ts.map +1 -0
  37. package/dist/components/index.js +10 -0
  38. package/dist/components/index.js.map +1 -0
  39. package/dist/components/nodes.d.ts +43 -0
  40. package/dist/components/nodes.d.ts.map +1 -0
  41. package/dist/components/nodes.js +111 -0
  42. package/dist/components/nodes.js.map +1 -0
  43. package/dist/editor/CoralEditor.d.ts +29 -0
  44. package/dist/editor/CoralEditor.d.ts.map +1 -0
  45. package/dist/editor/CoralEditor.js +112 -0
  46. package/dist/editor/CoralEditor.js.map +1 -0
  47. package/dist/editor/FileControls.d.ts +34 -0
  48. package/dist/editor/FileControls.d.ts.map +1 -0
  49. package/dist/editor/FileControls.js +139 -0
  50. package/dist/editor/FileControls.js.map +1 -0
  51. package/dist/editor/LayoutControls.d.ts +41 -0
  52. package/dist/editor/LayoutControls.d.ts.map +1 -0
  53. package/dist/editor/LayoutControls.js +124 -0
  54. package/dist/editor/LayoutControls.js.map +1 -0
  55. package/dist/editor/converter.d.ts +37 -0
  56. package/dist/editor/converter.d.ts.map +1 -0
  57. package/dist/editor/converter.js +256 -0
  58. package/dist/editor/converter.js.map +1 -0
  59. package/dist/editor/index.d.ts +8 -0
  60. package/dist/editor/index.d.ts.map +1 -0
  61. package/dist/editor/index.js +8 -0
  62. package/dist/editor/index.js.map +1 -0
  63. package/dist/file/deserialize.d.ts +15 -0
  64. package/dist/file/deserialize.d.ts.map +1 -0
  65. package/dist/file/deserialize.js +145 -0
  66. package/dist/file/deserialize.js.map +1 -0
  67. package/dist/file/index.d.ts +15 -0
  68. package/dist/file/index.d.ts.map +1 -0
  69. package/dist/file/index.js +20 -0
  70. package/dist/file/index.js.map +1 -0
  71. package/dist/file/migrate.d.ts +29 -0
  72. package/dist/file/migrate.d.ts.map +1 -0
  73. package/dist/file/migrate.js +103 -0
  74. package/dist/file/migrate.js.map +1 -0
  75. package/dist/file/schema.d.ts +385 -0
  76. package/dist/file/schema.d.ts.map +1 -0
  77. package/dist/file/schema.js +180 -0
  78. package/dist/file/schema.js.map +1 -0
  79. package/dist/file/serialize.d.ts +30 -0
  80. package/dist/file/serialize.d.ts.map +1 -0
  81. package/dist/file/serialize.js +218 -0
  82. package/dist/file/serialize.js.map +1 -0
  83. package/dist/file/validate.d.ts +21 -0
  84. package/dist/file/validate.d.ts.map +1 -0
  85. package/dist/file/validate.js +165 -0
  86. package/dist/file/validate.js.map +1 -0
  87. package/dist/index.d.ts +24 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +42 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/layout/elk.d.ts +77 -0
  92. package/dist/layout/elk.d.ts.map +1 -0
  93. package/dist/layout/elk.js +379 -0
  94. package/dist/layout/elk.js.map +1 -0
  95. package/dist/layout/index.d.ts +12 -0
  96. package/dist/layout/index.d.ts.map +1 -0
  97. package/dist/layout/index.js +12 -0
  98. package/dist/layout/index.js.map +1 -0
  99. package/dist/layout/nodeSizing.d.ts +65 -0
  100. package/dist/layout/nodeSizing.d.ts.map +1 -0
  101. package/dist/layout/nodeSizing.js +319 -0
  102. package/dist/layout/nodeSizing.js.map +1 -0
  103. package/dist/layout/positionStability.d.ts +73 -0
  104. package/dist/layout/positionStability.d.ts.map +1 -0
  105. package/dist/layout/positionStability.js +199 -0
  106. package/dist/layout/positionStability.js.map +1 -0
  107. package/dist/layout/useAxisConstrain.d.ts +20 -0
  108. package/dist/layout/useAxisConstrain.d.ts.map +1 -0
  109. package/dist/layout/useAxisConstrain.js +106 -0
  110. package/dist/layout/useAxisConstrain.js.map +1 -0
  111. package/dist/layout/useDiagramState.d.ts +92 -0
  112. package/dist/layout/useDiagramState.d.ts.map +1 -0
  113. package/dist/layout/useDiagramState.js +256 -0
  114. package/dist/layout/useDiagramState.js.map +1 -0
  115. package/dist/layout/useLayoutHistory.d.ts +53 -0
  116. package/dist/layout/useLayoutHistory.d.ts.map +1 -0
  117. package/dist/layout/useLayoutHistory.js +124 -0
  118. package/dist/layout/useLayoutHistory.js.map +1 -0
  119. package/dist/properties/NodePropertiesPanel.d.ts +47 -0
  120. package/dist/properties/NodePropertiesPanel.d.ts.map +1 -0
  121. package/dist/properties/NodePropertiesPanel.js +199 -0
  122. package/dist/properties/NodePropertiesPanel.js.map +1 -0
  123. package/dist/properties/index.d.ts +10 -0
  124. package/dist/properties/index.d.ts.map +1 -0
  125. package/dist/properties/index.js +10 -0
  126. package/dist/properties/index.js.map +1 -0
  127. package/dist/properties/propertyUtils.d.ts +60 -0
  128. package/dist/properties/propertyUtils.d.ts.map +1 -0
  129. package/dist/properties/propertyUtils.js +89 -0
  130. package/dist/properties/propertyUtils.js.map +1 -0
  131. package/dist/settings/FontSettingsForm.d.ts +28 -0
  132. package/dist/settings/FontSettingsForm.d.ts.map +1 -0
  133. package/dist/settings/FontSettingsForm.js +129 -0
  134. package/dist/settings/FontSettingsForm.js.map +1 -0
  135. package/dist/settings/LayoutSettingsForm.d.ts +37 -0
  136. package/dist/settings/LayoutSettingsForm.d.ts.map +1 -0
  137. package/dist/settings/LayoutSettingsForm.js +165 -0
  138. package/dist/settings/LayoutSettingsForm.js.map +1 -0
  139. package/dist/settings/SettingsPanel.d.ts +55 -0
  140. package/dist/settings/SettingsPanel.d.ts.map +1 -0
  141. package/dist/settings/SettingsPanel.js +84 -0
  142. package/dist/settings/SettingsPanel.js.map +1 -0
  143. package/dist/settings/index.d.ts +13 -0
  144. package/dist/settings/index.d.ts.map +1 -0
  145. package/dist/settings/index.js +13 -0
  146. package/dist/settings/index.js.map +1 -0
  147. package/dist/settings/useSettings.d.ts +51 -0
  148. package/dist/settings/useSettings.d.ts.map +1 -0
  149. package/dist/settings/useSettings.js +154 -0
  150. package/dist/settings/useSettings.js.map +1 -0
  151. package/dist/text-editor/SplitEditor.d.ts +72 -0
  152. package/dist/text-editor/SplitEditor.d.ts.map +1 -0
  153. package/dist/text-editor/SplitEditor.js +172 -0
  154. package/dist/text-editor/SplitEditor.js.map +1 -0
  155. package/dist/text-editor/TextEditor.d.ts +53 -0
  156. package/dist/text-editor/TextEditor.d.ts.map +1 -0
  157. package/dist/text-editor/TextEditor.js +181 -0
  158. package/dist/text-editor/TextEditor.js.map +1 -0
  159. package/dist/text-editor/hooks/useBidirectionalSync.d.ts +106 -0
  160. package/dist/text-editor/hooks/useBidirectionalSync.d.ts.map +1 -0
  161. package/dist/text-editor/hooks/useBidirectionalSync.js +151 -0
  162. package/dist/text-editor/hooks/useBidirectionalSync.js.map +1 -0
  163. package/dist/text-editor/index.d.ts +9 -0
  164. package/dist/text-editor/index.d.ts.map +1 -0
  165. package/dist/text-editor/index.js +11 -0
  166. package/dist/text-editor/index.js.map +1 -0
  167. package/dist/types.d.ts +242 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +5 -0
  170. package/dist/types.js.map +1 -0
  171. package/dist/waypoints/index.d.ts +8 -0
  172. package/dist/waypoints/index.d.ts.map +1 -0
  173. package/dist/waypoints/index.js +7 -0
  174. package/dist/waypoints/index.js.map +1 -0
  175. package/dist/waypoints/operations.d.ts +29 -0
  176. package/dist/waypoints/operations.d.ts.map +1 -0
  177. package/dist/waypoints/operations.js +85 -0
  178. package/dist/waypoints/operations.js.map +1 -0
  179. package/dist/waypoints/router.d.ts +23 -0
  180. package/dist/waypoints/router.d.ts.map +1 -0
  181. package/dist/waypoints/router.js +109 -0
  182. package/dist/waypoints/router.js.map +1 -0
  183. package/dist/waypoints/types.d.ts +15 -0
  184. package/dist/waypoints/types.d.ts.map +1 -0
  185. package/dist/waypoints/types.js +5 -0
  186. package/dist/waypoints/types.js.map +1 -0
  187. package/dist/waypoints/useWaypointManager.d.ts +38 -0
  188. package/dist/waypoints/useWaypointManager.d.ts.map +1 -0
  189. package/dist/waypoints/useWaypointManager.js +106 -0
  190. package/dist/waypoints/useWaypointManager.js.map +1 -0
  191. package/package.json +76 -0
@@ -0,0 +1,382 @@
1
+ /**
2
+ * Connection Validation Utilities (CORAL-REQ-010)
3
+ *
4
+ * Validates connections against notation rules and provides
5
+ * compatibility information for visual feedback.
6
+ */
7
+ import { getNotation } from '@coral-viz/render';
8
+ import { symbolRegistry } from '@coral-viz/render';
9
+ // ============================================================================
10
+ // Port Direction Validation
11
+ // ============================================================================
12
+ /**
13
+ * Check if port directions are compatible
14
+ *
15
+ * @param sourceDirection - Direction of source port (in/out/inout)
16
+ * @param targetDirection - Direction of target port (in/out/inout)
17
+ */
18
+ export function checkPortDirection(sourceDirection, targetDirection) {
19
+ // Source must be 'out' or 'inout'
20
+ if (sourceDirection === 'in') {
21
+ return {
22
+ valid: false,
23
+ hasWarning: false,
24
+ reason: 'port-direction-mismatch',
25
+ message: "Input port cannot be used as source; only 'out' or 'inout' ports can originate connections",
26
+ };
27
+ }
28
+ // Target must be 'in' or 'inout'
29
+ if (targetDirection === 'out') {
30
+ return {
31
+ valid: false,
32
+ hasWarning: false,
33
+ reason: 'port-direction-mismatch',
34
+ message: "Output port cannot be used as target; only 'in' or 'inout' ports can receive connections",
35
+ };
36
+ }
37
+ return { valid: true, hasWarning: false };
38
+ }
39
+ // ============================================================================
40
+ // Max Connections Validation
41
+ // ============================================================================
42
+ /**
43
+ * Check if adding a connection would exceed max connections
44
+ *
45
+ * @param nodeId - Node ID to check
46
+ * @param portId - Port ID (optional)
47
+ * @param maxConnections - Maximum allowed connections (undefined = unlimited)
48
+ * @param existingEdges - Current edges in the diagram
49
+ * @param checkAs - Check as 'source' (outgoing) or 'target' (incoming)
50
+ */
51
+ export function checkMaxConnections(nodeId, portId, maxConnections, existingEdges, checkAs) {
52
+ if (maxConnections === undefined) {
53
+ return { valid: true, hasWarning: false };
54
+ }
55
+ // Count existing connections
56
+ let count;
57
+ if (checkAs === 'source') {
58
+ count = existingEdges.filter((e) => {
59
+ if (e.source !== nodeId)
60
+ return false;
61
+ if (portId && e.sourcePort && e.sourcePort !== portId)
62
+ return false;
63
+ return true;
64
+ }).length;
65
+ }
66
+ else {
67
+ count = existingEdges.filter((e) => {
68
+ if (e.target !== nodeId)
69
+ return false;
70
+ if (portId && e.targetPort && e.targetPort !== portId)
71
+ return false;
72
+ return true;
73
+ }).length;
74
+ }
75
+ if (count >= maxConnections) {
76
+ const direction = checkAs === 'source' ? 'outgoing' : 'incoming';
77
+ return {
78
+ valid: true,
79
+ hasWarning: true,
80
+ reason: 'max-connections-exceeded',
81
+ message: `Node has reached maximum ${direction} connections (${maxConnections})`,
82
+ };
83
+ }
84
+ return { valid: true, hasWarning: false };
85
+ }
86
+ // ============================================================================
87
+ // Symbol Connection Rules
88
+ // ============================================================================
89
+ /**
90
+ * Find ALL matching connection rules for source symbol/variant
91
+ */
92
+ function findConnectionRules(notation, sourceSymbolId, sourceVariant) {
93
+ const rules = [];
94
+ // First try to find rules with matching variant
95
+ if (sourceVariant) {
96
+ const variantRules = notation.connectionRules.filter((rule) => rule.from === sourceSymbolId && rule.fromVariant === sourceVariant);
97
+ if (variantRules.length > 0) {
98
+ return variantRules; // Variant-specific rules take precedence
99
+ }
100
+ }
101
+ // Fall back to rules without variant
102
+ return notation.connectionRules.filter((rule) => rule.from === sourceSymbolId && !rule.fromVariant);
103
+ }
104
+ /**
105
+ * Find a single matching connection rule (for backward compatibility)
106
+ */
107
+ function findConnectionRule(notation, sourceSymbolId, sourceVariant) {
108
+ const rules = findConnectionRules(notation, sourceSymbolId, sourceVariant);
109
+ return rules[0];
110
+ }
111
+ /**
112
+ * Check if source symbol can connect to target symbol
113
+ */
114
+ function checkSymbolConnection(notation, sourceInfo, targetInfo, existingEdges) {
115
+ const rules = findConnectionRules(notation, sourceInfo.symbolId, sourceInfo.variant);
116
+ // No rules found for source - warn but allow
117
+ if (rules.length === 0) {
118
+ return {
119
+ valid: true,
120
+ hasWarning: true,
121
+ message: `No connection rules defined for ${sourceInfo.symbolId}`,
122
+ };
123
+ }
124
+ // Check if ANY rule allows this target
125
+ // Also collect all allowed targets for error message
126
+ const allAllowedTargets = new Set();
127
+ let matchingRule;
128
+ for (const rule of rules) {
129
+ rule.to.forEach((t) => allAllowedTargets.add(t));
130
+ if (rule.to.includes(targetInfo.symbolId)) {
131
+ matchingRule = rule;
132
+ break;
133
+ }
134
+ }
135
+ // Check if all rules have empty 'to' arrays (no outgoing allowed)
136
+ if (allAllowedTargets.size === 0) {
137
+ return {
138
+ valid: false,
139
+ hasWarning: false,
140
+ reason: 'symbol-not-allowed',
141
+ message: `${sourceInfo.symbolId}${sourceInfo.variant ? ` (${sourceInfo.variant})` : ''} cannot have outgoing connections`,
142
+ };
143
+ }
144
+ // Target not allowed by any rule
145
+ if (!matchingRule) {
146
+ return {
147
+ valid: false,
148
+ hasWarning: false,
149
+ reason: 'symbol-not-allowed',
150
+ message: `${sourceInfo.symbolId} cannot connect to ${targetInfo.symbolId}`,
151
+ };
152
+ }
153
+ // Check constraints on the matching rule
154
+ if (matchingRule.constraints) {
155
+ // Check maxOutgoing
156
+ if (matchingRule.constraints.maxOutgoing !== undefined) {
157
+ const outgoingCount = existingEdges.filter((e) => e.source === sourceInfo.id).length;
158
+ if (outgoingCount >= matchingRule.constraints.maxOutgoing) {
159
+ return {
160
+ valid: true,
161
+ hasWarning: true,
162
+ reason: 'max-connections-exceeded',
163
+ message: `${sourceInfo.symbolId} has reached maximum outgoing connections (${matchingRule.constraints.maxOutgoing})`,
164
+ };
165
+ }
166
+ }
167
+ }
168
+ // Check if target symbol has maxIncoming constraint
169
+ const targetRule = findConnectionRule(notation, targetInfo.symbolId, targetInfo.variant);
170
+ if (targetRule?.constraints?.maxIncoming !== undefined) {
171
+ const maxIncoming = targetRule.constraints.maxIncoming;
172
+ const incomingCount = existingEdges.filter((e) => e.target === targetInfo.id).length;
173
+ // maxIncoming: 0 means "never allowed" - use symbol-not-allowed
174
+ if (maxIncoming === 0) {
175
+ return {
176
+ valid: false,
177
+ hasWarning: false,
178
+ reason: 'symbol-not-allowed',
179
+ message: `${targetInfo.symbolId}${targetInfo.variant ? ` (${targetInfo.variant})` : ''} cannot receive incoming connections`,
180
+ };
181
+ }
182
+ if (incomingCount >= maxIncoming) {
183
+ return {
184
+ valid: true,
185
+ hasWarning: true,
186
+ reason: 'max-connections-exceeded',
187
+ message: `${targetInfo.symbolId} has reached maximum incoming connections (${maxIncoming})`,
188
+ };
189
+ }
190
+ }
191
+ return { valid: true, hasWarning: false };
192
+ }
193
+ // ============================================================================
194
+ // Port-Level Validation
195
+ // ============================================================================
196
+ /**
197
+ * Get ports for a symbol
198
+ */
199
+ function getSymbolPorts(symbolId, variant) {
200
+ const symbol = symbolRegistry.get(symbolId);
201
+ if (!symbol) {
202
+ return [
203
+ { id: 'in', anchor: 'NORTH', direction: 'in' },
204
+ { id: 'out', anchor: 'SOUTH', direction: 'out' },
205
+ ];
206
+ }
207
+ // Check for variant-specific ports
208
+ if (variant && symbol.variants?.[variant]?.ports) {
209
+ return symbol.variants[variant].ports;
210
+ }
211
+ // Fall back to symbol ports
212
+ if (symbol.ports && symbol.ports.length > 0) {
213
+ return symbol.ports;
214
+ }
215
+ // Default ports
216
+ return [
217
+ { id: 'in', anchor: 'NORTH', direction: 'in' },
218
+ { id: 'out', anchor: 'SOUTH', direction: 'out' },
219
+ ];
220
+ }
221
+ /**
222
+ * Validate port-level compatibility
223
+ */
224
+ function validatePorts(sourceInfo, targetInfo, sourcePortId, targetPortId, existingEdges = []) {
225
+ const sourcePorts = getSymbolPorts(sourceInfo.symbolId, sourceInfo.variant);
226
+ const targetPorts = getSymbolPorts(targetInfo.symbolId, targetInfo.variant);
227
+ // Find the specific ports if IDs provided
228
+ const sourcePort = sourcePortId
229
+ ? sourcePorts.find((p) => p.id === sourcePortId)
230
+ : sourcePorts.find((p) => p.direction === 'out' || p.direction === 'inout');
231
+ const targetPort = targetPortId
232
+ ? targetPorts.find((p) => p.id === targetPortId)
233
+ : targetPorts.find((p) => p.direction === 'in' || p.direction === 'inout');
234
+ // Check port directions if we have both ports
235
+ if (sourcePort && targetPort) {
236
+ const directionCheck = checkPortDirection(sourcePort.direction, targetPort.direction);
237
+ if (!directionCheck.valid) {
238
+ return directionCheck;
239
+ }
240
+ let warning;
241
+ // Check max connections on source port
242
+ if (sourcePort.maxConnections !== undefined) {
243
+ const maxCheck = checkMaxConnections(sourceInfo.id, sourcePort.id, sourcePort.maxConnections, existingEdges, 'source');
244
+ if (!maxCheck.valid) {
245
+ return maxCheck;
246
+ }
247
+ if (maxCheck.hasWarning)
248
+ warning = maxCheck;
249
+ }
250
+ // Check max connections on target port
251
+ if (targetPort.maxConnections !== undefined) {
252
+ const maxCheck = checkMaxConnections(targetInfo.id, targetPort.id, targetPort.maxConnections, existingEdges, 'target');
253
+ if (!maxCheck.valid) {
254
+ return maxCheck;
255
+ }
256
+ if (maxCheck.hasWarning && !warning)
257
+ warning = maxCheck;
258
+ }
259
+ if (warning)
260
+ return warning;
261
+ }
262
+ return { valid: true, hasWarning: false };
263
+ }
264
+ // ============================================================================
265
+ // Main Validation Function
266
+ // ============================================================================
267
+ /**
268
+ * Validate a connection against notation rules
269
+ *
270
+ * @param connection - The connection to validate
271
+ * @param context - Validation context with notation and node info
272
+ * @returns Validation result with compatibility status and message
273
+ */
274
+ export function validateConnection(connection, context) {
275
+ const { sourceNodeId, targetNodeId, sourcePortId, targetPortId } = connection;
276
+ const { notationId, nodeInfo, existingEdges } = context;
277
+ // Check for self-connection
278
+ if (sourceNodeId === targetNodeId) {
279
+ return {
280
+ valid: false,
281
+ hasWarning: false,
282
+ reason: 'self-connection',
283
+ message: 'A node cannot connect to itself',
284
+ };
285
+ }
286
+ // Get node info
287
+ const sourceInfo = nodeInfo.get(sourceNodeId);
288
+ const targetInfo = nodeInfo.get(targetNodeId);
289
+ // Handle unknown nodes (warn but allow)
290
+ if (!sourceInfo) {
291
+ return {
292
+ valid: true,
293
+ hasWarning: true,
294
+ message: `Unknown source node: ${sourceNodeId}`,
295
+ };
296
+ }
297
+ if (!targetInfo) {
298
+ return {
299
+ valid: true,
300
+ hasWarning: true,
301
+ message: `Unknown target node: ${targetNodeId}`,
302
+ };
303
+ }
304
+ // Get notation
305
+ const notation = getNotation(notationId);
306
+ if (!notation) {
307
+ return {
308
+ valid: true,
309
+ hasWarning: true,
310
+ message: `Unknown notation: ${notationId}. Connection allowed but not validated.`,
311
+ };
312
+ }
313
+ // Check symbol-level rules
314
+ const symbolCheck = checkSymbolConnection(notation, sourceInfo, targetInfo, existingEdges);
315
+ if (!symbolCheck.valid) {
316
+ return symbolCheck;
317
+ }
318
+ // Check port-level rules
319
+ const portCheck = validatePorts(sourceInfo, targetInfo, sourcePortId, targetPortId, existingEdges);
320
+ if (!portCheck.valid) {
321
+ return portCheck;
322
+ }
323
+ // Merge any warnings (preserve reason from the first warning)
324
+ if (symbolCheck.hasWarning || portCheck.hasWarning) {
325
+ const primary = symbolCheck.hasWarning ? symbolCheck : portCheck;
326
+ return {
327
+ valid: true,
328
+ hasWarning: true,
329
+ reason: primary.reason,
330
+ message: primary.message,
331
+ };
332
+ }
333
+ return { valid: true, hasWarning: false };
334
+ }
335
+ // ============================================================================
336
+ // Batch Validation for Edges
337
+ // ============================================================================
338
+ /**
339
+ * Get compatibility status for multiple edges
340
+ *
341
+ * When validating existing edges, we exclude the edge being validated from
342
+ * the existingEdges count. This prevents false positives where an edge at
343
+ * the maxConnections limit would fail validation because it counts itself.
344
+ *
345
+ * @param edges - Edges to check
346
+ * @param context - Validation context
347
+ * @returns Array of edge compatibility info
348
+ */
349
+ export function getEdgeCompatibility(edges, context) {
350
+ return edges.map((edge) => {
351
+ // Create a modified context that excludes the current edge
352
+ // This is needed because when validating an EXISTING edge,
353
+ // we shouldn't count it in the max connections check
354
+ const otherEdges = context.existingEdges.filter((e) => !(e.source === edge.source && e.target === edge.target));
355
+ const edgeContext = {
356
+ ...context,
357
+ existingEdges: otherEdges,
358
+ };
359
+ const validation = validateConnection({
360
+ sourceNodeId: edge.source,
361
+ targetNodeId: edge.target,
362
+ sourcePortId: edge.sourcePort,
363
+ targetPortId: edge.targetPort,
364
+ }, edgeContext);
365
+ let status;
366
+ if (!validation.valid) {
367
+ status = 'incompatible';
368
+ }
369
+ else if (validation.hasWarning) {
370
+ status = 'warning';
371
+ }
372
+ else {
373
+ status = 'compatible';
374
+ }
375
+ return {
376
+ edgeId: edge.id,
377
+ status,
378
+ validation,
379
+ };
380
+ });
381
+ }
382
+ //# sourceMappingURL=validateConnection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateConnection.js","sourceRoot":"","sources":["../../src/compatibility/validateConnection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Edit Context
3
+ *
4
+ * Provides label editing callbacks to React Flow nodes.
5
+ * This is necessary because React Flow doesn't pass custom callbacks directly to nodes.
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ /**
9
+ * Callback type for label edits
10
+ */
11
+ export type OnLabelEditCallback = (nodeId: string, newLabel: string) => void;
12
+ /**
13
+ * Edit context value
14
+ */
15
+ interface EditContextValue {
16
+ /** Callback when a node label is edited */
17
+ onLabelEdit?: OnLabelEditCallback;
18
+ /** ID of the node currently being edited (only one at a time) */
19
+ editingNodeId: string | null;
20
+ /** Start editing a node */
21
+ startEditing: (nodeId: string) => void;
22
+ /** Stop editing */
23
+ stopEditing: () => void;
24
+ }
25
+ /**
26
+ * Props for EditProvider
27
+ */
28
+ export interface EditProviderProps {
29
+ children: ReactNode;
30
+ onLabelEdit?: OnLabelEditCallback;
31
+ }
32
+ /**
33
+ * Provider component for edit context
34
+ */
35
+ export declare function EditProvider({ children, onLabelEdit }: EditProviderProps): React.ReactElement;
36
+ /**
37
+ * Hook to access edit context
38
+ */
39
+ export declare function useEditContext(): EditContextValue;
40
+ /**
41
+ * Hook to check if a specific node is being edited
42
+ */
43
+ export declare function useIsEditing(nodeId: string): boolean;
44
+ export {};
45
+ //# sourceMappingURL=EditContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditContext.d.ts","sourceRoot":"","sources":["../../src/components/EditContext.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;AAE7E;;GAEG;AACH,UAAU,gBAAgB;IACxB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,mBAAmB,CAAC;IAClC,iEAAiE;IACjE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,2BAA2B;IAC3B,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,mBAAmB;IACnB,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AASD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,KAAK,CAAC,YAAY,CAgB7F;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,gBAAgB,CAEjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGpD"}
@@ -0,0 +1,41 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * Edit Context
4
+ *
5
+ * Provides label editing callbacks to React Flow nodes.
6
+ * This is necessary because React Flow doesn't pass custom callbacks directly to nodes.
7
+ */
8
+ import { createContext, useContext, useCallback, useState } from 'react';
9
+ const EditContext = createContext({
10
+ onLabelEdit: undefined,
11
+ editingNodeId: null,
12
+ startEditing: () => { },
13
+ stopEditing: () => { },
14
+ });
15
+ /**
16
+ * Provider component for edit context
17
+ */
18
+ export function EditProvider({ children, onLabelEdit }) {
19
+ const [editingNodeId, setEditingNodeId] = useState(null);
20
+ const startEditing = useCallback((nodeId) => {
21
+ setEditingNodeId(nodeId);
22
+ }, []);
23
+ const stopEditing = useCallback(() => {
24
+ setEditingNodeId(null);
25
+ }, []);
26
+ return (_jsx(EditContext.Provider, { value: { onLabelEdit, editingNodeId, startEditing, stopEditing }, children: children }));
27
+ }
28
+ /**
29
+ * Hook to access edit context
30
+ */
31
+ export function useEditContext() {
32
+ return useContext(EditContext);
33
+ }
34
+ /**
35
+ * Hook to check if a specific node is being edited
36
+ */
37
+ export function useIsEditing(nodeId) {
38
+ const { editingNodeId } = useEditContext();
39
+ return editingNodeId === nodeId;
40
+ }
41
+ //# sourceMappingURL=EditContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditContext.js","sourceRoot":"","sources":["../../src/components/EditContext.tsx"],"names":[],"mappings":";AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAqBzF,MAAM,WAAW,GAAG,aAAa,CAAmB;IAClD,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,IAAI;IACnB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC;CACtB,CAAC,CAAC;AAUH;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAqB;IACvE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExE,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,MAAc,EAAE,EAAE;QAClD,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;QACnC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,CACL,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,YACnF,QAAQ,GACY,CACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,EAAE,aAAa,EAAE,GAAG,cAAc,EAAE,CAAC;IAC3C,OAAO,aAAa,KAAK,MAAM,CAAC;AAClC,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * ShapeRenderer - Renders SVG shapes from ShapeDefinition
3
+ *
4
+ * This component takes a shape definition and renders the SVG path
5
+ * with proper scaling and styling.
6
+ */
7
+ import type { ShapeDefinition } from '../types.js';
8
+ export interface ShapeRendererProps {
9
+ /** Shape definition to render */
10
+ shape: ShapeDefinition;
11
+ /** Width to render at (overrides defaultSize) */
12
+ width?: number;
13
+ /** Height to render at (overrides defaultSize) */
14
+ height?: number;
15
+ /** Fill color */
16
+ fill?: string;
17
+ /** Stroke color */
18
+ stroke?: string;
19
+ /** Stroke width */
20
+ strokeWidth?: number;
21
+ /** Stroke dash array (for dashed/dotted lines) */
22
+ strokeDasharray?: string;
23
+ /** Additional CSS class */
24
+ className?: string;
25
+ /** Parameter overrides for parametric shapes */
26
+ parameters?: Record<string, number | string | boolean>;
27
+ /** Enable hand-drawn sketch mode (SVG turbulence filter) */
28
+ sketch?: boolean;
29
+ }
30
+ /**
31
+ * Render an SVG shape from a ShapeDefinition
32
+ */
33
+ export declare function ShapeRenderer({ shape, width, height, fill, stroke, strokeWidth, strokeDasharray, className, parameters, sketch, }: ShapeRendererProps): import("react").JSX.Element;
34
+ export default ShapeRenderer;
35
+ //# sourceMappingURL=ShapeRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShapeRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ShapeRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,kBAAkB;IACjC,iCAAiC;IACjC,KAAK,EAAE,eAAe,CAAC;IACvB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACvD,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAsCD;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,MAAM,EACN,IAAgB,EAChB,MAAkB,EAClB,WAAe,EACf,eAAe,EACf,SAAS,EACT,UAAU,EACV,MAAM,GACP,EAAE,kBAAkB,+BAyEpB;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Parse a viewBox string into values
4
+ */
5
+ function parseViewBox(viewBox) {
6
+ const parts = viewBox.split(' ').map(Number);
7
+ return {
8
+ x: parts[0] || 0,
9
+ y: parts[1] || 0,
10
+ width: parts[2] || 100,
11
+ height: parts[3] || 60,
12
+ };
13
+ }
14
+ /**
15
+ * Generate an SVG path with rounded corners for rectangle shapes
16
+ */
17
+ function getRoundedRectPath(width, height, cornerRadius) {
18
+ const r = Math.min(cornerRadius, width / 2, height / 2);
19
+ return `
20
+ M ${r},0
21
+ L ${width - r},0
22
+ Q ${width},0 ${width},${r}
23
+ L ${width},${height - r}
24
+ Q ${width},${height} ${width - r},${height}
25
+ L ${r},${height}
26
+ Q 0,${height} 0,${height - r}
27
+ L 0,${r}
28
+ Q 0,0 ${r},0
29
+ Z
30
+ `.replace(/\s+/g, ' ').trim();
31
+ }
32
+ /**
33
+ * Render an SVG shape from a ShapeDefinition
34
+ */
35
+ export function ShapeRenderer({ shape, width, height, fill = '#ffffff', stroke = '#000000', strokeWidth = 2, strokeDasharray, className, parameters, sketch, }) {
36
+ const finalWidth = width ?? shape.defaultSize.width;
37
+ const finalHeight = height ?? shape.defaultSize.height;
38
+ const viewBox = parseViewBox(shape.viewBox);
39
+ // Calculate scale factors
40
+ const scaleX = finalWidth / viewBox.width;
41
+ const scaleY = finalHeight / viewBox.height;
42
+ // Determine the path to use
43
+ let pathData = shape.path;
44
+ // Handle parametric shapes (like rounded rectangles)
45
+ if (shape.id === 'rectangle' && parameters?.cornerRadius) {
46
+ const cornerRadius = Number(parameters.cornerRadius) || 0;
47
+ if (cornerRadius > 0) {
48
+ pathData = getRoundedRectPath(viewBox.width, viewBox.height, cornerRadius);
49
+ }
50
+ }
51
+ // For strokeOnly shapes (like actor), don't fill
52
+ const finalFill = shape.strokeOnly ? 'none' : fill;
53
+ // Sketch mode: slightly thicker stroke for hand-drawn feel
54
+ const finalStrokeWidth = sketch
55
+ ? (strokeWidth + 0.5) / Math.min(scaleX, scaleY)
56
+ : strokeWidth / Math.min(scaleX, scaleY);
57
+ // Unique filter ID for sketch mode
58
+ const filterId = sketch ? `sketch-wobble-${shape.id}` : undefined;
59
+ // Handle compound paths (multiple subpaths)
60
+ const paths = pathData.split(' M ').map((p, i) => (i === 0 ? p : 'M ' + p));
61
+ const pathProps = {
62
+ d: pathData,
63
+ fill: finalFill,
64
+ stroke,
65
+ strokeWidth: finalStrokeWidth,
66
+ strokeDasharray,
67
+ strokeLinecap: 'round',
68
+ strokeLinejoin: 'round',
69
+ ...(filterId ? { filter: `url(#${filterId})` } : {}),
70
+ };
71
+ return (_jsxs("svg", { width: finalWidth, height: finalHeight, viewBox: `0 0 ${viewBox.width} ${viewBox.height}`, className: className, style: {
72
+ display: 'block',
73
+ overflow: 'visible',
74
+ }, children: [sketch && (_jsx("defs", { children: _jsxs("filter", { id: filterId, x: "-5%", y: "-5%", width: "110%", height: "110%", children: [_jsx("feTurbulence", { type: "turbulence", baseFrequency: "0.04", numOctaves: "3", seed: shape.id.length, result: "turbulence" }), _jsx("feDisplacementMap", { in: "SourceGraphic", in2: "turbulence", scale: 1.5, xChannelSelector: "R", yChannelSelector: "G" })] }) })), paths.length === 1 ? (_jsx("path", { ...pathProps })) : (_jsx("g", { children: _jsx("path", { ...pathProps }) }))] }));
75
+ }
76
+ export default ShapeRenderer;
77
+ //# sourceMappingURL=ShapeRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShapeRenderer.js","sourceRoot":"","sources":["../../src/components/ShapeRenderer.tsx"],"names":[],"mappings":"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"}