@motiadev/workbench 0.14.0-beta.165-285707 → 0.15.0-beta.165

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 (236) hide show
  1. package/dist/index.d.ts +189 -10
  2. package/dist/index.html +1 -1
  3. package/dist/index.js +1065 -7
  4. package/dist/middleware.d.ts +66 -8
  5. package/dist/middleware.js +694 -86
  6. package/dist/motia-plugin/__tests__/generator.test.ts +129 -0
  7. package/dist/motia-plugin/__tests__/resolver.test.ts +82 -0
  8. package/dist/motia-plugin/__tests__/validator.test.ts +71 -0
  9. package/dist/motia-plugin/{generator.js → generator.ts} +37 -35
  10. package/dist/motia-plugin/hmr.ts +123 -0
  11. package/dist/motia-plugin/index.ts +183 -0
  12. package/dist/motia-plugin/{resolver.d.ts → resolver.ts} +38 -5
  13. package/dist/motia-plugin/types.ts +198 -0
  14. package/dist/motia-plugin/{utils.d.ts → utils.ts} +17 -4
  15. package/dist/motia-plugin/validator.ts +197 -0
  16. package/dist/src/App.tsx +41 -0
  17. package/dist/src/components/NotFoundPage.tsx +11 -0
  18. package/dist/src/components/bottom-panel.tsx +39 -0
  19. package/dist/src/components/flow/base-edge.tsx +61 -0
  20. package/dist/src/components/flow/flow-loader.tsx +3 -0
  21. package/dist/src/components/flow/flow-page.tsx +75 -0
  22. package/dist/src/components/flow/flow-tab-menu-item.tsx +52 -0
  23. package/dist/src/components/flow/flow-view.tsx +66 -0
  24. package/dist/src/components/flow/hooks/use-get-flow-state.tsx +171 -0
  25. package/dist/src/components/flow/hooks/use-save-workflow-config.ts +25 -0
  26. package/dist/src/components/flow/node-organizer.tsx +103 -0
  27. package/dist/src/components/flow/nodes/api-flow-node.tsx +6 -0
  28. package/dist/src/components/flow/nodes/cron-flow-node.tsx +6 -0
  29. package/dist/src/components/flow/nodes/event-flow-node.tsx +6 -0
  30. package/dist/src/components/flow/nodes/noop-flow-node.tsx +6 -0
  31. package/dist/src/components/header/deploy-button.tsx +110 -0
  32. package/dist/src/components/header/header.tsx +39 -0
  33. package/dist/src/components/root-motia.tsx +10 -0
  34. package/dist/src/components/top-panel.tsx +40 -0
  35. package/dist/src/components/tutorial/engine/tutorial-engine.ts +26 -0
  36. package/dist/src/components/tutorial/engine/tutorial-types.ts +26 -0
  37. package/dist/src/components/tutorial/engine/workbench-xpath.ts +53 -0
  38. package/dist/src/components/tutorial/hooks/tutorial-utils.ts +26 -0
  39. package/dist/src/components/tutorial/hooks/use-tutorial-engine.ts +213 -0
  40. package/dist/src/components/tutorial/hooks/use-tutorial.ts +14 -0
  41. package/dist/src/components/tutorial/tutorial-button.tsx +46 -0
  42. package/dist/src/components/tutorial/tutorial-step.tsx +82 -0
  43. package/dist/src/components/tutorial/tutorial.tsx +59 -0
  44. package/dist/src/components/ui/json-editor.tsx +68 -0
  45. package/dist/src/components/ui/table.tsx +75 -0
  46. package/dist/src/components/ui/theme-toggle.tsx +54 -0
  47. package/dist/src/components/ui/tooltip.tsx +26 -0
  48. package/dist/src/hooks/use-debounced.ts +22 -0
  49. package/dist/src/hooks/use-fetch-flows.ts +33 -0
  50. package/dist/src/hooks/use-mobile.ts +19 -0
  51. package/dist/src/hooks/use-update-handle-positions.ts +42 -0
  52. package/dist/src/index.css +5 -5
  53. package/dist/src/lib/__tests__/utils.test.ts +110 -0
  54. package/dist/src/lib/motia-analytics.ts +140 -0
  55. package/dist/src/lib/plugins.tsx +132 -0
  56. package/dist/src/lib/utils.ts +37 -0
  57. package/dist/src/main.tsx +30 -0
  58. package/dist/src/project-view-mode.tsx +32 -0
  59. package/dist/src/publicComponents/api-node.tsx +26 -0
  60. package/dist/src/publicComponents/base-node/base-handle.tsx +50 -0
  61. package/dist/src/publicComponents/base-node/base-node.tsx +114 -0
  62. package/dist/src/publicComponents/base-node/code-display.tsx +119 -0
  63. package/dist/src/publicComponents/base-node/emits.tsx +17 -0
  64. package/dist/src/publicComponents/base-node/feature-card.tsx +32 -0
  65. package/dist/src/publicComponents/base-node/language-indicator.tsx +131 -0
  66. package/dist/src/publicComponents/base-node/node-header.tsx +49 -0
  67. package/dist/src/publicComponents/base-node/node-sidebar.tsx +41 -0
  68. package/dist/src/publicComponents/base-node/subscribe.tsx +13 -0
  69. package/dist/src/publicComponents/cron-node.tsx +24 -0
  70. package/dist/src/publicComponents/event-node.tsx +20 -0
  71. package/dist/src/publicComponents/node-props.tsx +15 -0
  72. package/dist/src/publicComponents/noop-node.tsx +19 -0
  73. package/dist/src/setupTests.ts +1 -0
  74. package/dist/src/stores/use-app-tabs-store.ts +49 -0
  75. package/dist/src/stores/use-flow-store.ts +31 -0
  76. package/dist/src/stores/use-global-store.ts +24 -0
  77. package/dist/src/stores/use-motia-config-store.ts +36 -0
  78. package/dist/src/stores/use-tabs-store.ts +34 -0
  79. package/dist/src/system-view-mode.tsx +28 -0
  80. package/dist/src/types/endpoint.ts +12 -0
  81. package/dist/src/types/file.ts +7 -0
  82. package/dist/src/types/flow.ts +103 -0
  83. package/eslint.config.cjs +22 -0
  84. package/jest.config.cjs +68 -0
  85. package/package.json +53 -51
  86. package/dist/motia-plugin/__tests__/generator.test.d.ts +0 -1
  87. package/dist/motia-plugin/__tests__/generator.test.js +0 -97
  88. package/dist/motia-plugin/__tests__/resolver.test.d.ts +0 -1
  89. package/dist/motia-plugin/__tests__/resolver.test.js +0 -64
  90. package/dist/motia-plugin/__tests__/validator.test.d.ts +0 -1
  91. package/dist/motia-plugin/__tests__/validator.test.js +0 -59
  92. package/dist/motia-plugin/generator.d.ts +0 -78
  93. package/dist/motia-plugin/hmr.d.ts +0 -22
  94. package/dist/motia-plugin/hmr.js +0 -100
  95. package/dist/motia-plugin/index.d.ts +0 -3
  96. package/dist/motia-plugin/index.js +0 -153
  97. package/dist/motia-plugin/resolver.js +0 -92
  98. package/dist/motia-plugin/types.d.ts +0 -169
  99. package/dist/motia-plugin/types.js +0 -36
  100. package/dist/motia-plugin/utils.js +0 -75
  101. package/dist/motia-plugin/validator.d.ts +0 -19
  102. package/dist/motia-plugin/validator.js +0 -163
  103. package/dist/src/App.d.ts +0 -2
  104. package/dist/src/App.js +0 -35
  105. package/dist/src/components/NotFoundPage.d.ts +0 -1
  106. package/dist/src/components/NotFoundPage.js +0 -3
  107. package/dist/src/components/bottom-panel.d.ts +0 -1
  108. package/dist/src/components/bottom-panel.js +0 -15
  109. package/dist/src/components/flow/base-edge.d.ts +0 -3
  110. package/dist/src/components/flow/base-edge.js +0 -39
  111. package/dist/src/components/flow/flow-loader.d.ts +0 -1
  112. package/dist/src/components/flow/flow-loader.js +0 -4
  113. package/dist/src/components/flow/flow-page.d.ts +0 -1
  114. package/dist/src/components/flow/flow-page.js +0 -25
  115. package/dist/src/components/flow/flow-tab-menu-item.d.ts +0 -1
  116. package/dist/src/components/flow/flow-tab-menu-item.js +0 -18
  117. package/dist/src/components/flow/flow-view.d.ts +0 -12
  118. package/dist/src/components/flow/flow-view.js +0 -22
  119. package/dist/src/components/flow/hooks/use-get-flow-state.d.ts +0 -10
  120. package/dist/src/components/flow/hooks/use-get-flow-state.js +0 -133
  121. package/dist/src/components/flow/hooks/use-save-workflow-config.d.ts +0 -2
  122. package/dist/src/components/flow/hooks/use-save-workflow-config.js +0 -22
  123. package/dist/src/components/flow/node-organizer.d.ts +0 -10
  124. package/dist/src/components/flow/node-organizer.js +0 -82
  125. package/dist/src/components/flow/nodes/api-flow-node.d.ts +0 -2
  126. package/dist/src/components/flow/nodes/api-flow-node.js +0 -5
  127. package/dist/src/components/flow/nodes/cron-flow-node.d.ts +0 -2
  128. package/dist/src/components/flow/nodes/cron-flow-node.js +0 -5
  129. package/dist/src/components/flow/nodes/event-flow-node.d.ts +0 -2
  130. package/dist/src/components/flow/nodes/event-flow-node.js +0 -5
  131. package/dist/src/components/flow/nodes/noop-flow-node.d.ts +0 -2
  132. package/dist/src/components/flow/nodes/noop-flow-node.js +0 -5
  133. package/dist/src/components/header/deploy-button.d.ts +0 -1
  134. package/dist/src/components/header/deploy-button.js +0 -28
  135. package/dist/src/components/header/header.d.ts +0 -2
  136. package/dist/src/components/header/header.js +0 -23
  137. package/dist/src/components/root-motia.d.ts +0 -2
  138. package/dist/src/components/root-motia.js +0 -7
  139. package/dist/src/components/top-panel.d.ts +0 -1
  140. package/dist/src/components/top-panel.js +0 -15
  141. package/dist/src/components/tutorial/engine/tutorial-engine.d.ts +0 -12
  142. package/dist/src/components/tutorial/engine/tutorial-engine.js +0 -36
  143. package/dist/src/components/tutorial/engine/tutorial-types.d.ts +0 -22
  144. package/dist/src/components/tutorial/engine/tutorial-types.js +0 -1
  145. package/dist/src/components/tutorial/engine/workbench-xpath.d.ts +0 -45
  146. package/dist/src/components/tutorial/engine/workbench-xpath.js +0 -45
  147. package/dist/src/components/tutorial/hooks/tutorial-utils.d.ts +0 -1
  148. package/dist/src/components/tutorial/hooks/tutorial-utils.js +0 -17
  149. package/dist/src/components/tutorial/hooks/use-tutorial-engine.d.ts +0 -15
  150. package/dist/src/components/tutorial/hooks/use-tutorial-engine.js +0 -183
  151. package/dist/src/components/tutorial/hooks/use-tutorial.d.ts +0 -5
  152. package/dist/src/components/tutorial/hooks/use-tutorial.js +0 -10
  153. package/dist/src/components/tutorial/tutorial-button.d.ts +0 -2
  154. package/dist/src/components/tutorial/tutorial-button.js +0 -21
  155. package/dist/src/components/tutorial/tutorial-step.d.ts +0 -14
  156. package/dist/src/components/tutorial/tutorial-step.js +0 -19
  157. package/dist/src/components/tutorial/tutorial.d.ts +0 -2
  158. package/dist/src/components/tutorial/tutorial.js +0 -32
  159. package/dist/src/components/ui/json-editor.d.ts +0 -12
  160. package/dist/src/components/ui/json-editor.js +0 -35
  161. package/dist/src/components/ui/table.d.ts +0 -10
  162. package/dist/src/components/ui/table.js +0 -20
  163. package/dist/src/components/ui/theme-toggle.d.ts +0 -2
  164. package/dist/src/components/ui/theme-toggle.js +0 -19
  165. package/dist/src/components/ui/tooltip.d.ts +0 -6
  166. package/dist/src/components/ui/tooltip.js +0 -3
  167. package/dist/src/hooks/use-debounced.d.ts +0 -1
  168. package/dist/src/hooks/use-debounced.js +0 -18
  169. package/dist/src/hooks/use-fetch-flows.d.ts +0 -1
  170. package/dist/src/hooks/use-fetch-flows.js +0 -26
  171. package/dist/src/hooks/use-mobile.d.ts +0 -1
  172. package/dist/src/hooks/use-mobile.js +0 -15
  173. package/dist/src/hooks/use-update-handle-positions.d.ts +0 -10
  174. package/dist/src/hooks/use-update-handle-positions.js +0 -35
  175. package/dist/src/lib/__tests__/utils.test.d.ts +0 -1
  176. package/dist/src/lib/__tests__/utils.test.js +0 -94
  177. package/dist/src/lib/motia-analytics.d.ts +0 -38
  178. package/dist/src/lib/motia-analytics.js +0 -132
  179. package/dist/src/lib/plugins.d.ts +0 -2
  180. package/dist/src/lib/plugins.js +0 -105
  181. package/dist/src/lib/utils.d.ts +0 -7
  182. package/dist/src/lib/utils.js +0 -34
  183. package/dist/src/main.d.ts +0 -2
  184. package/dist/src/main.js +0 -17
  185. package/dist/src/project-view-mode.d.ts +0 -1
  186. package/dist/src/project-view-mode.js +0 -20
  187. package/dist/src/publicComponents/api-node.d.ts +0 -5
  188. package/dist/src/publicComponents/api-node.js +0 -5
  189. package/dist/src/publicComponents/base-node/base-handle.d.ts +0 -9
  190. package/dist/src/publicComponents/base-node/base-handle.js +0 -8
  191. package/dist/src/publicComponents/base-node/base-node.d.ts +0 -15
  192. package/dist/src/publicComponents/base-node/base-node.js +0 -30
  193. package/dist/src/publicComponents/base-node/code-display.d.ts +0 -9
  194. package/dist/src/publicComponents/base-node/code-display.js +0 -64
  195. package/dist/src/publicComponents/base-node/emits.d.ts +0 -5
  196. package/dist/src/publicComponents/base-node/emits.js +0 -5
  197. package/dist/src/publicComponents/base-node/feature-card.d.ts +0 -10
  198. package/dist/src/publicComponents/base-node/feature-card.js +0 -5
  199. package/dist/src/publicComponents/base-node/language-indicator.d.ts +0 -10
  200. package/dist/src/publicComponents/base-node/language-indicator.js +0 -29
  201. package/dist/src/publicComponents/base-node/node-header.d.ts +0 -13
  202. package/dist/src/publicComponents/base-node/node-header.js +0 -30
  203. package/dist/src/publicComponents/base-node/node-sidebar.d.ts +0 -14
  204. package/dist/src/publicComponents/base-node/node-sidebar.js +0 -9
  205. package/dist/src/publicComponents/base-node/subscribe.d.ts +0 -4
  206. package/dist/src/publicComponents/base-node/subscribe.js +0 -4
  207. package/dist/src/publicComponents/cron-node.d.ts +0 -4
  208. package/dist/src/publicComponents/cron-node.js +0 -6
  209. package/dist/src/publicComponents/event-node.d.ts +0 -4
  210. package/dist/src/publicComponents/event-node.js +0 -5
  211. package/dist/src/publicComponents/node-props.d.ts +0 -21
  212. package/dist/src/publicComponents/node-props.js +0 -1
  213. package/dist/src/publicComponents/noop-node.d.ts +0 -4
  214. package/dist/src/publicComponents/noop-node.js +0 -5
  215. package/dist/src/setupTests.d.ts +0 -1
  216. package/dist/src/setupTests.js +0 -1
  217. package/dist/src/stores/use-app-tabs-store.d.ts +0 -16
  218. package/dist/src/stores/use-app-tabs-store.js +0 -31
  219. package/dist/src/stores/use-flow-store.d.ts +0 -21
  220. package/dist/src/stores/use-flow-store.js +0 -16
  221. package/dist/src/stores/use-global-store.d.ts +0 -18
  222. package/dist/src/stores/use-global-store.js +0 -12
  223. package/dist/src/stores/use-motia-config-store.d.ts +0 -12
  224. package/dist/src/stores/use-motia-config-store.js +0 -24
  225. package/dist/src/stores/use-tabs-store.d.ts +0 -19
  226. package/dist/src/stores/use-tabs-store.js +0 -22
  227. package/dist/src/system-view-mode.d.ts +0 -1
  228. package/dist/src/system-view-mode.js +0 -10
  229. package/dist/src/types/endpoint.d.ts +0 -14
  230. package/dist/src/types/endpoint.js +0 -1
  231. package/dist/src/types/file.d.ts +0 -7
  232. package/dist/src/types/file.js +0 -1
  233. package/dist/src/types/flow.d.ts +0 -115
  234. package/dist/src/types/flow.js +0 -1
  235. package/dist/tsconfig.app.tsbuildinfo +0 -1
  236. package/dist/tsconfig.node.tsbuildinfo +0 -1
@@ -1,163 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validatePluginConfig = validatePluginConfig;
4
- exports.validatePlugins = validatePlugins;
5
- const fs_1 = require("fs");
6
- const zod_1 = require("zod");
7
- const types_1 = require("./types");
8
- const utils_1 = require("./utils");
9
- /**
10
- * Zod schema for WorkbenchPlugin configuration.
11
- * Provides runtime type validation with detailed error messages.
12
- */
13
- const WorkbenchPluginSchema = zod_1.z.object({
14
- packageName: zod_1.z
15
- .string()
16
- .min(1, 'packageName is required and cannot be empty')
17
- .refine((name) => name.startsWith('~/') || name.startsWith('@') || /^[a-z0-9-_]+$/i.test(name), {
18
- message: 'packageName must be a valid npm package name or local path (starting with ~/)',
19
- }),
20
- componentName: zod_1.z.string().optional(),
21
- position: zod_1.z
22
- .enum(['top', 'bottom'])
23
- .optional()
24
- .refine((pos) => pos === undefined || (0, types_1.isValidPosition)(pos), {
25
- message: 'position must be either "top" or "bottom"',
26
- }),
27
- label: zod_1.z.string().optional(),
28
- labelIcon: zod_1.z.string().optional(),
29
- cssImports: zod_1.z.array(zod_1.z.string()).optional(),
30
- props: zod_1.z.record(zod_1.z.any(), zod_1.z.any()).optional(),
31
- });
32
- /**
33
- * Validates a single plugin configuration.
34
- *
35
- * @param plugin - The plugin configuration to validate
36
- * @param index - The index of the plugin in the array (for error messages)
37
- * @returns A validation result with errors, warnings, and normalized plugin
38
- */
39
- function validatePluginConfig(plugin, index) {
40
- const errors = [];
41
- const warnings = [];
42
- if (typeof plugin !== 'object' || plugin === null) {
43
- return {
44
- valid: false,
45
- errors: [`Plugin at index ${index}: expected object, got ${typeof plugin}`],
46
- warnings: [],
47
- };
48
- }
49
- try {
50
- const result = WorkbenchPluginSchema.safeParse(plugin);
51
- if (!result.success) {
52
- result.error.issues.forEach((err) => {
53
- const path = err.path.join('.');
54
- errors.push(`Plugin at index ${index}, field "${path}": ${err.message}`);
55
- });
56
- return { valid: false, errors, warnings };
57
- }
58
- const validatedPlugin = result.data;
59
- if ((0, utils_1.isLocalPlugin)(validatedPlugin.packageName)) {
60
- const resolvedPath = (0, utils_1.resolveLocalPath)(validatedPlugin.packageName);
61
- if (!(0, fs_1.existsSync)(resolvedPath)) {
62
- warnings.push(`Plugin at index ${index}: local path "${validatedPlugin.packageName}" does not exist at "${resolvedPath}". ` +
63
- `Make sure the path is correct relative to the project root.`);
64
- }
65
- }
66
- if (!validatedPlugin.label) {
67
- warnings.push(`Plugin at index ${index}: "label" not specified, will use default "${types_1.CONSTANTS.DEFAULTS.LABEL}"`);
68
- }
69
- if (!validatedPlugin.labelIcon) {
70
- warnings.push(`Plugin at index ${index}: "labelIcon" not specified, will use default "${types_1.CONSTANTS.DEFAULTS.ICON}"`);
71
- }
72
- if (!validatedPlugin.position) {
73
- warnings.push(`Plugin at index ${index}: "position" not specified, will use default "${types_1.CONSTANTS.DEFAULTS.POSITION}"`);
74
- }
75
- if (validatedPlugin.props && Object.keys(validatedPlugin.props).length === 0) {
76
- warnings.push(`Plugin at index ${index}: "props" is an empty object`);
77
- }
78
- if (validatedPlugin.cssImports) {
79
- if (validatedPlugin.cssImports.length === 0) {
80
- warnings.push(`Plugin at index ${index}: "cssImports" is an empty array`);
81
- }
82
- validatedPlugin.cssImports.forEach((cssImport, cssIndex) => {
83
- if (!cssImport || cssImport.trim() === '') {
84
- warnings.push(`Plugin at index ${index}: cssImport at index ${cssIndex} is empty or whitespace`);
85
- }
86
- });
87
- }
88
- return {
89
- valid: true,
90
- errors: [],
91
- warnings,
92
- plugin: validatedPlugin,
93
- };
94
- }
95
- catch (error) {
96
- return {
97
- valid: false,
98
- errors: [`Plugin at index ${index}: unexpected validation error: ${error}`],
99
- warnings: [],
100
- };
101
- }
102
- }
103
- /**
104
- * Validates an array of plugin configurations.
105
- *
106
- * @param plugins - Array of plugin configurations to validate
107
- * @param options - Validation options
108
- * @returns Combined validation result for all plugins
109
- */
110
- function validatePlugins(plugins, options = {}) {
111
- const allErrors = [];
112
- const allWarnings = [];
113
- const validatedPlugins = [];
114
- if (!Array.isArray(plugins)) {
115
- return {
116
- valid: false,
117
- errors: [`Expected plugins to be an array, got ${typeof plugins}`],
118
- warnings: [],
119
- };
120
- }
121
- if (plugins.length === 0) {
122
- console.warn('[motia-plugins] No plugins provided to validate');
123
- return {
124
- valid: true,
125
- errors: [],
126
- warnings: ['No plugins configured'],
127
- };
128
- }
129
- for (let i = 0; i < plugins.length; i++) {
130
- const result = validatePluginConfig(plugins[i], i);
131
- allErrors.push(...result.errors);
132
- allWarnings.push(...result.warnings);
133
- if (result.valid && result.plugin) {
134
- validatedPlugins.push(result.plugin);
135
- }
136
- if (options.failFast && result.errors.length > 0) {
137
- break;
138
- }
139
- }
140
- const packageNames = validatedPlugins.map((p) => p.packageName);
141
- const duplicates = packageNames.filter((name, index) => packageNames.indexOf(name) !== index);
142
- if (duplicates.length > 0) {
143
- const uniqueDuplicates = [...new Set(duplicates)];
144
- uniqueDuplicates.forEach((dup) => {
145
- allWarnings.push(`Duplicate package name found: "${dup}". This may cause conflicts.`);
146
- });
147
- }
148
- const valid = allErrors.length === 0;
149
- if (valid) {
150
- console.log(`[motia-plugins] ✓ Validated ${validatedPlugins.length} plugin(s) successfully`);
151
- if (allWarnings.length > 0) {
152
- console.warn(`[motia-plugins] Found ${allWarnings.length} warning(s)`);
153
- }
154
- }
155
- else {
156
- console.error(`[motia-plugins] ✗ Validation failed with ${allErrors.length} error(s)`);
157
- }
158
- return {
159
- valid,
160
- errors: allErrors,
161
- warnings: allWarnings,
162
- };
163
- }
package/dist/src/App.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import { type FC } from 'react';
2
- export declare const App: FC;
package/dist/src/App.js DELETED
@@ -1,35 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { memo, useEffect, useMemo } from 'react';
3
- import { FlowPage } from './components/flow/flow-page';
4
- import { FlowTabMenuItem } from './components/flow/flow-tab-menu-item';
5
- import { registerPluginTabs } from './lib/plugins';
6
- import { getViewModeFromURL } from './lib/utils';
7
- import { ProjectViewMode } from './project-view-mode';
8
- import { TabLocation, useAppTabsStore } from './stores/use-app-tabs-store';
9
- import { SystemViewMode } from './system-view-mode';
10
- const TAB_IDS = {
11
- FLOW: 'flow',
12
- LOGS: 'logs',
13
- };
14
- const topTabs = [
15
- {
16
- id: TAB_IDS.FLOW,
17
- tabLabel: FlowTabMenuItem,
18
- content: FlowPage,
19
- },
20
- ];
21
- export const App = memo(() => {
22
- const setTabs = useAppTabsStore((state) => state.setTabs);
23
- const addTab = useAppTabsStore((state) => state.addTab);
24
- useEffect(() => {
25
- const timeout = setTimeout(() => {
26
- setTabs(TabLocation.TOP, topTabs);
27
- registerPluginTabs(addTab);
28
- }, 10);
29
- return () => clearTimeout(timeout);
30
- }, [setTabs, addTab]);
31
- const viewMode = useMemo(getViewModeFromURL, []);
32
- const ViewComponent = viewMode === 'project' ? ProjectViewMode : SystemViewMode;
33
- return _jsx(ViewComponent, {});
34
- });
35
- App.displayName = 'App';
@@ -1 +0,0 @@
1
- export declare const NotFoundPage: () => import("react/jsx-runtime").JSX.Element;
@@ -1,3 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Header } from './header/header';
3
- export const NotFoundPage = () => (_jsxs("div", { className: "grid grid-rows-[auto_1fr] h-screen bg-background text-foreground", children: [_jsx(Header, {}), _jsxs("div", { className: "flex flex-col items-center justify-center", children: [_jsx("h1", { className: "text-4xl font-bold mb-4", children: "404 \u2013 Page Not Found" }), _jsx("p", { className: "text-lg opacity-80 mb-6", children: "This route doesn\u2019t exist." })] })] }));
@@ -1 +0,0 @@
1
- export declare const BottomPanel: import("react").MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element>;
@@ -1,15 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { CollapsiblePanel, TabsContent, TabsList, TabsTrigger } from '@motiadev/ui';
3
- import { memo } from 'react';
4
- import { useShallow } from 'zustand/react/shallow';
5
- import { TabLocation, useAppTabsStore } from '../stores/use-app-tabs-store';
6
- import { useTabsStore } from '../stores/use-tabs-store';
7
- const bottomTabsSelector = (state) => state.tabs[TabLocation.BOTTOM];
8
- const bottomPanelId = 'bottom-panel';
9
- export const BottomPanel = memo(() => {
10
- const defaultTab = useTabsStore((state) => state.tab.bottom);
11
- const setBottomTab = useTabsStore((state) => state.setBottomTab);
12
- const tabs = useAppTabsStore(useShallow(bottomTabsSelector));
13
- return (_jsx(CollapsiblePanel, { id: bottomPanelId, variant: 'tabs', defaultTab: defaultTab, onTabChange: setBottomTab, header: _jsx(TabsList, { children: tabs.map(({ id, tabLabel: Label }) => (_jsx(TabsTrigger, { value: id, "data-testid": `${id.toLowerCase()}-link`, className: "cursor-pointer", children: _jsx(Label, {}) }, id))) }), children: tabs.map(({ id, content: Element }) => (_jsx(TabsContent, { value: id, className: "h-full", children: _jsx(Element, {}) }, id))) }));
14
- });
15
- BottomPanel.displayName = 'BottomPanel';
@@ -1,3 +0,0 @@
1
- import { type EdgeProps } from '@xyflow/react';
2
- import type React from 'react';
3
- export declare const BaseEdge: React.FC<EdgeProps>;
@@ -1,39 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn, useThemeStore } from '@motiadev/ui';
3
- import { BaseEdge as BaseReactFlowEdge, EdgeLabelRenderer, getSmoothStepPath } from '@xyflow/react';
4
- import { cva } from 'class-variance-authority';
5
- const labelVariants = cva('absolute pointer-events-all text-cs border p-1 px-2', {
6
- variants: {
7
- color: {
8
- default: 'border-[#b3b3b3] bg-[#060014] text-gray-100 font-semibold border-solid rounded-full',
9
- conditional: 'bg-amber-300 border-amber-950 text-amber-950 border-solid font-semibold italic rounded-lg',
10
- },
11
- },
12
- defaultVariants: {
13
- color: 'default',
14
- },
15
- });
16
- export const BaseEdge = (props) => {
17
- const theme = useThemeStore((state) => state.theme);
18
- const { sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data } = props;
19
- const label = data?.label;
20
- const labelVariant = data?.labelVariant;
21
- const virtualColor = theme === 'dark' ? 'rgb(225, 225, 225)' : 'rgb(85, 85, 85)';
22
- const [edgePath, labelX, labelY] = getSmoothStepPath({
23
- sourceX,
24
- sourceY,
25
- targetX,
26
- targetY,
27
- sourcePosition,
28
- targetPosition,
29
- borderRadius: 20,
30
- offset: 10,
31
- });
32
- return (_jsxs(_Fragment, { children: [_jsx(BaseReactFlowEdge, { path: edgePath, style: {
33
- stroke: data?.variant === 'virtual' ? virtualColor : '#0094FF',
34
- strokeWidth: 2,
35
- shapeRendering: 'geometricPrecision',
36
- fill: 'none',
37
- mixBlendMode: 'screen',
38
- }, className: "edge-animated" }), label && (_jsx(EdgeLabelRenderer, { children: _jsx("div", { className: cn(labelVariants({ color: labelVariant })), style: { transform: `translateX(-50%) translateY(-50%) translate(${labelX}px, ${labelY}px)` }, children: _jsx("div", { className: "text-xs font-mono", children: label }) }) }))] }));
39
- };
@@ -1 +0,0 @@
1
- export declare const FlowLoader: () => import("react/jsx-runtime").JSX.Element;
@@ -1,4 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- export const FlowLoader = () => {
3
- return _jsx("div", { className: "absolute z-10 inset-0 w-full h-full bg-background" });
4
- };
@@ -1 +0,0 @@
1
- export declare const FlowPage: import("react").MemoExoticComponent<() => import("react/jsx-runtime").JSX.Element | null>;
@@ -1,25 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useStreamItem } from '@motiadev/stream-client-react';
3
- import { Button, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from '@motiadev/ui';
4
- import { ReactFlowProvider } from '@xyflow/react';
5
- import { ExternalLink, Workflow } from 'lucide-react';
6
- import { memo, useMemo } from 'react';
7
- import { useShallow } from 'zustand/react/shallow';
8
- import { motiaAnalytics } from '@/lib/motia-analytics';
9
- import { useFlowStore } from '@/stores/use-flow-store';
10
- import { FlowView } from './flow-view';
11
- export const FlowPage = memo(() => {
12
- const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
13
- const flows = useFlowStore(useShallow((state) => Object.values(state.flows)));
14
- const streamItemArgs = useMemo(() => ({ streamName: '__motia.flows', groupId: 'default', id: selectedFlowId ?? '' }), [selectedFlowId]);
15
- const { data: flow } = useStreamItem(streamItemArgs);
16
- const streamItemArgsConfig = useMemo(() => ({ streamName: '__motia.flowsConfig', groupId: 'default', id: selectedFlowId ?? '' }), [selectedFlowId]);
17
- const { data: flowConfig } = useStreamItem(streamItemArgsConfig);
18
- if (flows.length === 0 || flow?.error) {
19
- return (_jsx("div", { className: "flex w-full h-full bg-background", children: _jsxs(Empty, { children: [_jsxs(EmptyHeader, { children: [_jsx(EmptyMedia, { variant: "icon", children: _jsx(Workflow, {}) }), flow?.error ? (_jsxs(_Fragment, { children: [_jsx(EmptyTitle, { children: "Error loading flow" }), _jsx(EmptyDescription, { children: flow.error })] })) : (_jsxs(_Fragment, { children: [_jsx(EmptyTitle, { children: "No flows registered" }), _jsx(EmptyDescription, { children: "You haven't registered any flows yet. Get started by registering your first flow." })] }))] }), _jsx(EmptyContent, { children: _jsx(Button, { variant: "link", asChild: true, size: "sm", children: _jsxs("a", { href: "https://www.motia.dev/docs/development-guide/flows", target: "_blank", rel: "noopener noreferrer", onClick: () => motiaAnalytics.track('flows_docs_link_clicked'), children: ["Learn more ", _jsx(ExternalLink, {})] }) }) })] }) }));
20
- }
21
- if (!flow)
22
- return null;
23
- return (_jsx(ReactFlowProvider, { children: _jsx(FlowView, { flow: flow, flowConfig: flowConfig }) }));
24
- });
25
- FlowPage.displayName = 'FlowPage';
@@ -1 +0,0 @@
1
- export declare const FlowTabMenuItem: () => import("react/jsx-runtime").JSX.Element;
@@ -1,18 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@motiadev/ui';
3
- import { ChevronsUpDown, Workflow } from 'lucide-react';
4
- import { useShallow } from 'zustand/react/shallow';
5
- import { useFetchFlows } from '@/hooks/use-fetch-flows';
6
- import { motiaAnalytics } from '@/lib/motia-analytics';
7
- import { useFlowStore } from '@/stores/use-flow-store';
8
- export const FlowTabMenuItem = () => {
9
- useFetchFlows();
10
- const selectFlowId = useFlowStore((state) => state.selectFlowId);
11
- const flows = useFlowStore(useShallow((state) => Object.values(state.flows)));
12
- const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
13
- const handleFlowSelect = (flowId) => {
14
- selectFlowId(flowId);
15
- motiaAnalytics.track('flow_selected', { flow: flowId });
16
- };
17
- return (_jsxs("div", { className: "flex flex-row justify-center items-center gap-2 cursor-pointer", children: [_jsx(Workflow, {}), flows.length > 0 && selectedFlowId ? selectedFlowId : 'Flows', flows.length > 0 && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("div", { className: "flex flex-row justify-center items-center gap-2 cursor-pointer", "data-testid": "flows-dropdown-trigger", children: _jsx(ChevronsUpDown, { className: "size-4" }) }) }), _jsx(DropdownMenuContent, { className: "bg-background text-foreground flows-dropdown", children: flows.map((item) => (_jsx(DropdownMenuItem, { "data-testid": `dropdown-${item}`, className: "cursor-pointer gap-2 flow-link", onSelect: () => handleFlowSelect(item), children: item }, `dropdown-${item}`))) })] }))] }));
18
- };
@@ -1,12 +0,0 @@
1
- import { type Edge as ReactFlowEdge, type Node as ReactFlowNode } from '@xyflow/react';
2
- import type React from 'react';
3
- import type { EdgeData, FlowConfigResponse, FlowResponse, NodeData } from '@/types/flow';
4
- import '@xyflow/react/dist/style.css';
5
- export type FlowNode = ReactFlowNode<NodeData>;
6
- export type FlowEdge = ReactFlowEdge<EdgeData>;
7
- type Props = {
8
- flow: FlowResponse;
9
- flowConfig: FlowConfigResponse;
10
- };
11
- export declare const FlowView: React.FC<Props>;
12
- export {};
@@ -1,22 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Background, BackgroundVariant, ReactFlow, } from '@xyflow/react';
3
- import { useCallback, useState } from 'react';
4
- import { BaseEdge } from './base-edge';
5
- import { FlowLoader } from './flow-loader';
6
- import { useGetFlowState } from './hooks/use-get-flow-state';
7
- import { NodeOrganizer } from './node-organizer';
8
- import '@xyflow/react/dist/style.css';
9
- import { BackgroundEffect } from '@motiadev/ui';
10
- const edgeTypes = {
11
- base: BaseEdge,
12
- };
13
- export const FlowView = ({ flow, flowConfig }) => {
14
- const { nodes, edges, onNodesChange, onEdgesChange, nodeTypes } = useGetFlowState(flow, flowConfig);
15
- const [initialized, setInitialized] = useState(false);
16
- const onInitialized = useCallback(() => setInitialized(true), []);
17
- const onNodesChangeHandler = useCallback((changes) => onNodesChange(changes), [onNodesChange]);
18
- if (!nodeTypes) {
19
- return null;
20
- }
21
- return (_jsxs("div", { className: "w-full h-full relative", children: [!initialized && _jsx(FlowLoader, {}), _jsxs(ReactFlow, { minZoom: 0.1, nodes: nodes, edges: edges, nodeTypes: nodeTypes, edgeTypes: edgeTypes, onNodesChange: onNodesChangeHandler, onEdgesChange: onEdgesChange, className: "isolate", children: [_jsx(BackgroundEffect, {}), _jsx(Background, { variant: BackgroundVariant.Dots, gap: 20, size: 1 }), _jsx(NodeOrganizer, { onInitialized: onInitialized, nodes: nodes, edges: edges })] })] }));
22
- };
@@ -1,10 +0,0 @@
1
- import { type Edge, type Node } from '@xyflow/react';
2
- import type React from 'react';
3
- import type { EdgeData, FlowConfigResponse, FlowResponse, NodeData } from '@/types/flow';
4
- export declare const useGetFlowState: (flow: FlowResponse, flowConfig: FlowConfigResponse) => {
5
- nodes: Node<NodeData>[];
6
- edges: Edge<EdgeData>[];
7
- onNodesChange: import("@xyflow/react").OnNodesChange<Node<NodeData>>;
8
- onEdgesChange: import("@xyflow/react").OnEdgesChange<Edge<EdgeData>>;
9
- nodeTypes: Record<string, React.ComponentType<any>>;
10
- };
@@ -1,133 +0,0 @@
1
- import { useEdgesState, useNodesState } from '@xyflow/react';
2
- import isEqual from 'fast-deep-equal';
3
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
- import { ApiFlowNode } from '../nodes/api-flow-node';
5
- import { CronFlowNode } from '../nodes/cron-flow-node';
6
- import { EventFlowNode } from '../nodes/event-flow-node';
7
- import { NoopFlowNode } from '../nodes/noop-flow-node';
8
- import { useSaveWorkflowConfig } from './use-save-workflow-config';
9
- const DEFAULT_CONFIG = { x: 0, y: 0 };
10
- const getNodePosition = (flowConfig, stepName) => {
11
- return flowConfig?.config[stepName] || DEFAULT_CONFIG;
12
- };
13
- const nodeComponentCache = new Map();
14
- const BASE_NODE_TYPES = {
15
- event: EventFlowNode,
16
- api: ApiFlowNode,
17
- noop: NoopFlowNode,
18
- cron: CronFlowNode,
19
- };
20
- async function importFlow(flow, flowConfig) {
21
- const nodeTypes = { ...BASE_NODE_TYPES };
22
- const customNodePromises = flow.steps
23
- .filter((step) => step.nodeComponentPath)
24
- .map(async (step) => {
25
- const path = step.nodeComponentPath;
26
- // Check cache first
27
- if (nodeComponentCache.has(path)) {
28
- nodeTypes[path] = nodeComponentCache.get(path);
29
- return;
30
- }
31
- try {
32
- const module = await import(/* @vite-ignore */ `/@fs/${path}`);
33
- const component = module.Node ?? module.default;
34
- nodeComponentCache.set(path, component);
35
- nodeTypes[path] = component;
36
- }
37
- catch (error) {
38
- console.error(`Failed to load custom node component: ${path}`, error);
39
- }
40
- });
41
- await Promise.all(customNodePromises);
42
- const nodes = flow.steps.map((step) => ({
43
- id: step.id,
44
- type: step.nodeComponentPath || step.type,
45
- filePath: step.filePath,
46
- position: step.filePath ? getNodePosition(flowConfig, step.filePath) : DEFAULT_CONFIG,
47
- data: { ...step, nodeConfig: step.filePath ? getNodePosition(flowConfig, step.filePath) : DEFAULT_CONFIG },
48
- language: step.language,
49
- }));
50
- const edges = flow.edges.map((edge) => ({
51
- ...edge,
52
- type: 'base',
53
- }));
54
- return { nodes, edges, nodeTypes };
55
- }
56
- export const useGetFlowState = (flow, flowConfig) => {
57
- const [nodeTypes, setNodeTypes] = useState(BASE_NODE_TYPES);
58
- const [nodes, setNodes, onNodesChange] = useNodesState([]);
59
- const [edges, setEdges, onEdgesChange] = useEdgesState([]);
60
- const saveConfig = useSaveWorkflowConfig();
61
- const flowIdRef = useRef('');
62
- const saveTimeoutRef = useRef(null);
63
- const lastSavedConfigRef = useRef(null);
64
- const lastSavedFlowRef = useRef(null);
65
- // eslint-disable-next-line react-hooks/exhaustive-deps
66
- const memoizedFlowConfig = useMemo(() => flowConfig, [flowConfig?.id, flowConfig?.config]);
67
- useEffect(() => {
68
- if (!flow || flow.error)
69
- return;
70
- const hasSameConfig = isEqual(lastSavedConfigRef.current, memoizedFlowConfig?.config);
71
- const hasSameFlow = isEqual(lastSavedFlowRef.current, flow);
72
- if (hasSameConfig && hasSameFlow)
73
- return;
74
- lastSavedConfigRef.current = memoizedFlowConfig?.config;
75
- flowIdRef.current = flow.id;
76
- lastSavedFlowRef.current = flow;
77
- const importFlowAsync = async () => {
78
- try {
79
- const { nodes, edges, nodeTypes } = await importFlow(flow, flowConfig);
80
- setNodes(nodes);
81
- setEdges(edges);
82
- setNodeTypes(nodeTypes);
83
- }
84
- catch (error) {
85
- console.error('Failed to import flow:', error);
86
- }
87
- };
88
- importFlowAsync();
89
- }, [flow, memoizedFlowConfig, setNodes, setEdges, flowConfig]);
90
- const saveFlowConfig = useCallback((nodesToSave) => {
91
- if (saveTimeoutRef.current) {
92
- clearTimeout(saveTimeoutRef.current);
93
- }
94
- saveTimeoutRef.current = setTimeout(async () => {
95
- const steps = nodesToSave.reduce((acc, node) => {
96
- if (node.data.filePath) {
97
- acc[node.data.filePath] = {
98
- x: Math.round(node.position.x),
99
- y: Math.round(node.position.y),
100
- };
101
- if (node.data.nodeConfig?.sourceHandlePosition) {
102
- acc[node.data.filePath].sourceHandlePosition = node.data.nodeConfig.sourceHandlePosition;
103
- }
104
- if (node.data.nodeConfig?.targetHandlePosition) {
105
- acc[node.data.filePath].targetHandlePosition = node.data.nodeConfig.targetHandlePosition;
106
- }
107
- }
108
- return acc;
109
- }, {});
110
- if (!isEqual(steps, lastSavedConfigRef.current)) {
111
- lastSavedConfigRef.current = steps;
112
- const newConfig = { id: flowIdRef.current, config: steps };
113
- try {
114
- await saveConfig(newConfig);
115
- }
116
- catch (error) {
117
- console.error('Failed to save flow config:', error);
118
- }
119
- }
120
- }, 300);
121
- }, [saveConfig]);
122
- useEffect(() => {
123
- if (nodes.length > 0) {
124
- saveFlowConfig(nodes);
125
- }
126
- return () => {
127
- if (saveTimeoutRef.current) {
128
- clearTimeout(saveTimeoutRef.current);
129
- }
130
- };
131
- }, [nodes, saveFlowConfig]);
132
- return useMemo(() => ({ nodes, edges, onNodesChange, onEdgesChange, nodeTypes }), [nodes, edges, onNodesChange, onEdgesChange, nodeTypes]);
133
- };
@@ -1,2 +0,0 @@
1
- import type { FlowConfigResponse } from '@/types/flow';
2
- export declare const useSaveWorkflowConfig: () => (body: FlowConfigResponse) => Promise<any>;
@@ -1,22 +0,0 @@
1
- import { useCallback } from 'react';
2
- export const useSaveWorkflowConfig = () => {
3
- return useCallback(async (body) => {
4
- try {
5
- const response = await fetch(`/__motia/flows/${body.id}/config`, {
6
- method: 'POST',
7
- headers: {
8
- 'Content-Type': 'application/json',
9
- },
10
- body: JSON.stringify(body),
11
- });
12
- if (!response.ok) {
13
- throw new Error(`Failed to save config: ${response.statusText}`);
14
- }
15
- return await response.json();
16
- }
17
- catch (error) {
18
- console.error('Error saving workflow config:', error);
19
- throw error;
20
- }
21
- }, []);
22
- };
@@ -1,10 +0,0 @@
1
- import { type Edge, type Node } from '@xyflow/react';
2
- import type React from 'react';
3
- import type { EdgeData, NodeData } from '@/types/flow';
4
- type Props = {
5
- onInitialized: () => void;
6
- nodes: Node<NodeData>[];
7
- edges: Edge<EdgeData>[];
8
- };
9
- export declare const NodeOrganizer: React.FC<Props>;
10
- export {};
@@ -1,82 +0,0 @@
1
- import { useNodesInitialized, useReactFlow } from '@xyflow/react';
2
- import dagre from 'dagre';
3
- import isEqual from 'fast-deep-equal';
4
- import { useEffect, useRef } from 'react';
5
- const organizeNodes = (nodes, edges) => {
6
- const dagreGraph = new dagre.graphlib.Graph({ directed: true, compound: false, multigraph: false });
7
- dagreGraph.setDefaultEdgeLabel(() => ({}));
8
- dagreGraph.setGraph({ rankdir: 'LR', ranksep: 0, nodesep: 20, edgesep: 0 });
9
- nodes.forEach((node) => {
10
- if (node.position.x !== 0 || node.position.y !== 0) {
11
- dagreGraph.setNode(node.id, {
12
- width: node.measured?.width,
13
- height: node.measured?.height,
14
- x: node.position.x,
15
- y: node.position.y,
16
- });
17
- }
18
- else {
19
- dagreGraph.setNode(node.id, {
20
- width: node.measured?.width,
21
- height: node.measured?.height,
22
- });
23
- }
24
- });
25
- edges.forEach((edge) => {
26
- if (typeof edge.label === 'string') {
27
- dagreGraph.setEdge(edge.source, edge.target, {
28
- label: edge.label ?? '',
29
- width: edge.label.length * 40, // Add width for the label
30
- height: 30, // Add height for the label
31
- labelpos: 'c', // Position label in center
32
- });
33
- }
34
- else {
35
- dagreGraph.setEdge(edge.source, edge.target);
36
- }
37
- });
38
- dagre.layout(dagreGraph);
39
- return nodes.map((node) => {
40
- if (node.position.x !== 0 || node.position.y !== 0) {
41
- return node;
42
- }
43
- const { x, y } = dagreGraph.node(node.id);
44
- const position = {
45
- x: x - (node.measured?.width ?? 0) / 2,
46
- y: y - (node.measured?.height ?? 0) / 2,
47
- };
48
- return { ...node, position };
49
- });
50
- };
51
- export const NodeOrganizer = ({ onInitialized, nodes, edges }) => {
52
- const { setNodes, getNodes, getEdges, fitView } = useReactFlow();
53
- const nodesInitialized = useNodesInitialized();
54
- const initialized = useRef(false);
55
- const lastNodesRef = useRef([]);
56
- const lastEdgesRef = useRef([]);
57
- useEffect(() => {
58
- if (nodesInitialized) {
59
- if (isEqual(lastNodesRef.current, nodes) && isEqual(lastEdgesRef.current, edges)) {
60
- return;
61
- }
62
- lastNodesRef.current = nodes;
63
- lastEdgesRef.current = edges;
64
- try {
65
- const nodesToOrganize = nodes.some((node) => node.position.x === 0 && node.position.y === 0);
66
- if (nodesToOrganize) {
67
- const organizedNodes = organizeNodes(nodes, edges);
68
- setNodes(organizedNodes);
69
- }
70
- if (!initialized.current) {
71
- initialized.current = true;
72
- onInitialized();
73
- setTimeout(() => fitView(), 1);
74
- }
75
- }
76
- catch (error) {
77
- console.error('Error organizing nodes:', error);
78
- }
79
- }
80
- }, [nodesInitialized, onInitialized, setNodes, getNodes, getEdges, fitView, nodes, edges]);
81
- return null;
82
- };
@@ -1,2 +0,0 @@
1
- import type { ApiNodeProps } from '@/publicComponents/node-props';
2
- export declare const ApiFlowNode: ({ data }: ApiNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { ApiNode } from '@/publicComponents/api-node';
3
- export const ApiFlowNode = ({ data }) => {
4
- return _jsx(ApiNode, { data: data });
5
- };