@motiadev/workbench 0.8.2-beta.140-628177 → 0.8.2-beta.140-027880

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 (142) hide show
  1. package/dist/components.json +1 -1
  2. package/dist/index.d.ts +7 -7
  3. package/dist/index.js +5 -5
  4. package/dist/middleware.d.ts +1 -1
  5. package/dist/middleware.js +3 -3
  6. package/dist/motia-plugin/__tests__/generator.test.js +97 -0
  7. package/dist/motia-plugin/__tests__/resolver.test.d.ts +1 -0
  8. package/dist/motia-plugin/__tests__/resolver.test.js +64 -0
  9. package/dist/motia-plugin/__tests__/validator.test.d.ts +1 -0
  10. package/dist/motia-plugin/__tests__/validator.test.js +59 -0
  11. package/dist/motia-plugin/generator.d.ts +78 -0
  12. package/dist/motia-plugin/generator.js +128 -0
  13. package/dist/motia-plugin/hmr.d.ts +22 -0
  14. package/dist/motia-plugin/hmr.js +116 -0
  15. package/dist/motia-plugin/index.d.ts +3 -0
  16. package/dist/motia-plugin/index.js +152 -0
  17. package/dist/motia-plugin/resolver.d.ts +63 -0
  18. package/dist/motia-plugin/resolver.js +92 -0
  19. package/dist/motia-plugin/types.d.ts +169 -0
  20. package/dist/motia-plugin/types.js +36 -0
  21. package/dist/motia-plugin/utils.d.ts +57 -0
  22. package/dist/motia-plugin/utils.js +75 -0
  23. package/dist/motia-plugin/validator.d.ts +19 -0
  24. package/dist/motia-plugin/validator.js +163 -0
  25. package/dist/postcss.config.mjs +1 -1
  26. package/dist/src/App.d.ts +1 -1
  27. package/dist/src/App.js +1 -18
  28. package/dist/src/components/flow/base-edge.d.ts +2 -2
  29. package/dist/src/components/flow/base-edge.js +1 -1
  30. package/dist/src/components/flow/flow-page.js +2 -2
  31. package/dist/src/components/flow/flow-tab-menu-item.js +2 -2
  32. package/dist/src/components/flow/flow-view.d.ts +3 -3
  33. package/dist/src/components/flow/hooks/use-get-flow-state.d.ts +2 -2
  34. package/dist/src/components/flow/hooks/use-get-flow-state.js +0 -4
  35. package/dist/src/components/flow/hooks/use-save-workflow-config.d.ts +1 -1
  36. package/dist/src/components/flow/node-organizer.d.ts +3 -3
  37. package/dist/src/components/flow/nodes/api-flow-node.d.ts +1 -1
  38. package/dist/src/components/flow/nodes/cron-flow-node.d.ts +1 -1
  39. package/dist/src/components/flow/nodes/event-flow-node.d.ts +1 -1
  40. package/dist/src/components/flow/nodes/noop-flow-node.d.ts +1 -1
  41. package/dist/src/components/header/deploy-button.js +2 -2
  42. package/dist/src/components/header/header.d.ts +1 -1
  43. package/dist/src/components/header/header.js +2 -2
  44. package/dist/src/components/root-motia.d.ts +2 -1
  45. package/dist/src/components/tutorial/engine/tutorial-engine.d.ts +1 -1
  46. package/dist/src/components/tutorial/hooks/use-tutorial-engine.d.ts +1 -1
  47. package/dist/src/components/tutorial/hooks/use-tutorial.d.ts +1 -1
  48. package/dist/src/components/tutorial/tutorial-button.d.ts +1 -1
  49. package/dist/src/components/tutorial/tutorial-button.js +1 -1
  50. package/dist/src/components/tutorial/tutorial-step.d.ts +2 -2
  51. package/dist/src/components/tutorial/tutorial-step.js +1 -1
  52. package/dist/src/components/tutorial/tutorial.css +8 -8
  53. package/dist/src/components/ui/json-editor.d.ts +1 -1
  54. package/dist/src/components/ui/json-editor.js +1 -1
  55. package/dist/src/components/ui/table.js +1 -1
  56. package/dist/src/components/ui/theme-toggle.d.ts +1 -1
  57. package/dist/src/components/ui/tooltip.d.ts +1 -1
  58. package/dist/src/hooks/use-fetch-flows.js +1 -1
  59. package/dist/src/hooks/use-update-handle-positions.d.ts +1 -1
  60. package/dist/src/index.css +5 -5
  61. package/dist/src/lib/plugins.js +3 -3
  62. package/dist/src/main.js +2 -3
  63. package/dist/src/project-view-mode.js +1 -1
  64. package/dist/src/publicComponents/api-node.d.ts +2 -2
  65. package/dist/src/publicComponents/base-node/base-handle.d.ts +3 -2
  66. package/dist/src/publicComponents/base-node/base-node.d.ts +3 -2
  67. package/dist/src/publicComponents/base-node/base-node.js +1 -1
  68. package/dist/src/publicComponents/base-node/code-display.d.ts +2 -2
  69. package/dist/src/publicComponents/base-node/code-display.js +1 -1
  70. package/dist/src/publicComponents/base-node/emits.d.ts +2 -2
  71. package/dist/src/publicComponents/base-node/feature-card.d.ts +2 -2
  72. package/dist/src/publicComponents/base-node/language-indicator.d.ts +2 -2
  73. package/dist/src/publicComponents/base-node/node-header.d.ts +3 -2
  74. package/dist/src/publicComponents/base-node/node-sidebar.d.ts +2 -2
  75. package/dist/src/publicComponents/base-node/subscribe.d.ts +1 -1
  76. package/dist/src/publicComponents/cron-node.d.ts +3 -2
  77. package/dist/src/publicComponents/event-node.d.ts +3 -2
  78. package/dist/src/publicComponents/node-props.d.ts +1 -1
  79. package/dist/src/publicComponents/noop-node.d.ts +3 -2
  80. package/dist/src/stores/use-global-store.d.ts +0 -6
  81. package/dist/src/stores/use-global-store.js +0 -6
  82. package/dist/src/types/flow.d.ts +1 -1
  83. package/dist/tsconfig.app.tsbuildinfo +1 -1
  84. package/dist/tsconfig.node.tsbuildinfo +1 -1
  85. package/motia-plugin/__tests__/generator.test.ts +129 -0
  86. package/motia-plugin/__tests__/resolver.test.ts +82 -0
  87. package/motia-plugin/__tests__/validator.test.ts +71 -0
  88. package/motia-plugin/generator.ts +130 -0
  89. package/motia-plugin/hmr.ts +140 -0
  90. package/motia-plugin/index.ts +182 -0
  91. package/motia-plugin/resolver.ts +96 -0
  92. package/motia-plugin/types.ts +198 -0
  93. package/motia-plugin/utils.ts +70 -0
  94. package/motia-plugin/validator.ts +197 -0
  95. package/package.json +9 -9
  96. package/postcss.config.mjs +1 -1
  97. package/dist/src/components/observability/events/code/function-call.d.ts +0 -13
  98. package/dist/src/components/observability/events/code/function-call.js +0 -16
  99. package/dist/src/components/observability/events/event-icon.d.ts +0 -7
  100. package/dist/src/components/observability/events/event-icon.js +0 -16
  101. package/dist/src/components/observability/events/trace-emit-event.d.ts +0 -5
  102. package/dist/src/components/observability/events/trace-emit-event.js +0 -5
  103. package/dist/src/components/observability/events/trace-event.d.ts +0 -5
  104. package/dist/src/components/observability/events/trace-event.js +0 -20
  105. package/dist/src/components/observability/events/trace-log-event.d.ts +0 -5
  106. package/dist/src/components/observability/events/trace-log-event.js +0 -5
  107. package/dist/src/components/observability/events/trace-state-event.d.ts +0 -5
  108. package/dist/src/components/observability/events/trace-state-event.js +0 -5
  109. package/dist/src/components/observability/events/trace-stream-event.d.ts +0 -5
  110. package/dist/src/components/observability/events/trace-stream-event.js +0 -5
  111. package/dist/src/components/observability/hooks/use-get-endtime.d.ts +0 -2
  112. package/dist/src/components/observability/hooks/use-get-endtime.js +0 -15
  113. package/dist/src/components/observability/trace-item/trace-item-detail.d.ts +0 -8
  114. package/dist/src/components/observability/trace-item/trace-item-detail.js +0 -10
  115. package/dist/src/components/observability/trace-item/trace-item.d.ts +0 -10
  116. package/dist/src/components/observability/trace-item/trace-item.js +0 -14
  117. package/dist/src/components/observability/trace-status.d.ts +0 -8
  118. package/dist/src/components/observability/trace-status.js +0 -18
  119. package/dist/src/components/observability/trace-tab-label.d.ts +0 -1
  120. package/dist/src/components/observability/trace-tab-label.js +0 -5
  121. package/dist/src/components/observability/trace-timeline.d.ts +0 -6
  122. package/dist/src/components/observability/trace-timeline.js +0 -30
  123. package/dist/src/components/observability/traces-groups.d.ts +0 -9
  124. package/dist/src/components/observability/traces-groups.js +0 -9
  125. package/dist/src/components/observability/traces-page.d.ts +0 -1
  126. package/dist/src/components/observability/traces-page.js +0 -33
  127. package/dist/src/components/states/hooks/states-hooks.d.ts +0 -13
  128. package/dist/src/components/states/hooks/states-hooks.js +0 -26
  129. package/dist/src/components/states/state-details.d.ts +0 -7
  130. package/dist/src/components/states/state-details.js +0 -3
  131. package/dist/src/components/states/state-editor.d.ts +0 -7
  132. package/dist/src/components/states/state-editor.js +0 -71
  133. package/dist/src/components/states/state-sidebar.d.ts +0 -8
  134. package/dist/src/components/states/state-sidebar.js +0 -17
  135. package/dist/src/components/states/state-tab-label.d.ts +0 -1
  136. package/dist/src/components/states/state-tab-label.js +0 -5
  137. package/dist/src/components/states/states-page.d.ts +0 -1
  138. package/dist/src/components/states/states-page.js +0 -56
  139. package/dist/src/types/observability.d.ts +0 -78
  140. package/dist/vite-plugin-motia-plugins.d.ts +0 -9
  141. package/dist/vite-plugin-motia-plugins.js +0 -69
  142. /package/dist/{src/types/observability.js → motia-plugin/__tests__/generator.test.d.ts} +0 -0
@@ -0,0 +1,163 @@
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()).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.errors.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
+ }
@@ -1,6 +1,6 @@
1
- import path from 'path'
2
1
  import { dirname } from 'node:path'
3
2
  import { fileURLToPath } from 'node:url'
3
+ import path from 'path'
4
4
 
5
5
  const __dirname = dirname(fileURLToPath(import.meta.url))
6
6
 
package/dist/src/App.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { FC } from 'react';
1
+ import { type FC } from 'react';
2
2
  export declare const App: FC;
package/dist/src/App.js CHANGED
@@ -2,10 +2,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useMemo } from 'react';
3
3
  import { FlowPage } from './components/flow/flow-page';
4
4
  import { FlowTabMenuItem } from './components/flow/flow-tab-menu-item';
5
- import { TracingTabLabel } from './components/observability/trace-tab-label';
6
- import { TracesPage } from './components/observability/traces-page';
7
- import { StatesTabLabel } from './components/states/state-tab-label';
8
- import { StatesPage } from './components/states/states-page';
9
5
  import { registerPluginTabs } from './lib/plugins';
10
6
  import { getViewModeFromURL } from './lib/utils';
11
7
  import { ProjectViewMode } from './project-view-mode';
@@ -13,9 +9,7 @@ import { setAppTabs, TabLocation } from './stores/use-app-tabs-store';
13
9
  import { SystemViewMode } from './system-view-mode';
14
10
  const TAB_IDS = {
15
11
  FLOW: 'flow',
16
- TRACING: 'tracing',
17
12
  LOGS: 'logs',
18
- STATES: 'states',
19
13
  };
20
14
  const registerDefaultTabs = () => {
21
15
  const topTabs = [
@@ -25,18 +19,7 @@ const registerDefaultTabs = () => {
25
19
  content: FlowPage,
26
20
  },
27
21
  ];
28
- const bottomTabs = [
29
- {
30
- id: TAB_IDS.TRACING,
31
- tabLabel: TracingTabLabel,
32
- content: TracesPage,
33
- },
34
- {
35
- id: TAB_IDS.STATES,
36
- tabLabel: StatesTabLabel,
37
- content: StatesPage,
38
- },
39
- ];
22
+ const bottomTabs = [];
40
23
  setAppTabs(TabLocation.TOP, topTabs);
41
24
  setAppTabs(TabLocation.BOTTOM, bottomTabs);
42
25
  };
@@ -1,3 +1,3 @@
1
- import { EdgeProps } from '@xyflow/react';
2
- import React from 'react';
1
+ import { type EdgeProps } from '@xyflow/react';
2
+ import type React from 'react';
3
3
  export declare const BaseEdge: React.FC<EdgeProps>;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn, useThemeStore } from '@motiadev/ui';
2
3
  import { BaseEdge as BaseReactFlowEdge, EdgeLabelRenderer, getSmoothStepPath } from '@xyflow/react';
3
4
  import { cva } from 'class-variance-authority';
4
- import { cn, useThemeStore } from '@motiadev/ui';
5
5
  const labelVariants = cva('absolute pointer-events-all text-cs border p-1 px-2', {
6
6
  variants: {
7
7
  color: {
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useFlowStore } from '@/stores/use-flow-store';
3
2
  import { useStreamItem } from '@motiadev/stream-client-react';
4
- import { FlowView } from './flow-view';
5
3
  import { ReactFlowProvider } from '@xyflow/react';
4
+ import { useFlowStore } from '@/stores/use-flow-store';
5
+ import { FlowView } from './flow-view';
6
6
  export const FlowPage = () => {
7
7
  const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
8
8
  const { data: flow } = useStreamItem({
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@motiadev/ui';
3
3
  import { ChevronsUpDown, Workflow } from 'lucide-react';
4
- import { useFlowStore } from '@/stores/use-flow-store';
5
- import { useFetchFlows } from '@/hooks/use-fetch-flows';
6
4
  import { useShallow } from 'zustand/react/shallow';
5
+ import { useFetchFlows } from '@/hooks/use-fetch-flows';
7
6
  import { analytics } from '@/lib/analytics';
7
+ import { useFlowStore } from '@/stores/use-flow-store';
8
8
  export const FlowTabMenuItem = () => {
9
9
  useFetchFlows();
10
10
  const selectFlowId = useFlowStore((state) => state.selectFlowId);
@@ -1,6 +1,6 @@
1
- import { EdgeData, FlowConfigResponse, FlowResponse, NodeData } from '@/types/flow';
2
- import { Edge as ReactFlowEdge, Node as ReactFlowNode } from '@xyflow/react';
3
- import React from 'react';
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
4
  import '@xyflow/react/dist/style.css';
5
5
  export type FlowNode = ReactFlowNode<NodeData>;
6
6
  export type FlowEdge = ReactFlowEdge<EdgeData>;
@@ -1,6 +1,6 @@
1
+ import { type Edge, type Node } from '@xyflow/react';
2
+ import type React from 'react';
1
3
  import type { EdgeData, FlowConfigResponse, FlowResponse, NodeData } from '@/types/flow';
2
- import { Edge, Node } from '@xyflow/react';
3
- import React from 'react';
4
4
  export declare const useGetFlowState: (flow: FlowResponse, flowConfig: FlowConfigResponse) => {
5
5
  nodes: Node<NodeData>[];
6
6
  edges: Edge<EdgeData>[];
@@ -10,9 +10,7 @@ const DEFAULT_CONFIG = { x: 0, y: 0 };
10
10
  const getNodePosition = (flowConfig, stepName) => {
11
11
  return flowConfig?.config[stepName] || DEFAULT_CONFIG;
12
12
  };
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
13
  const nodeComponentCache = new Map();
15
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
14
  const BASE_NODE_TYPES = {
17
15
  event: EventFlowNode,
18
16
  api: ApiFlowNode,
@@ -20,7 +18,6 @@ const BASE_NODE_TYPES = {
20
18
  cron: CronFlowNode,
21
19
  };
22
20
  async function importFlow(flow, flowConfig) {
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
21
  const nodeTypes = { ...BASE_NODE_TYPES };
25
22
  const customNodePromises = flow.steps
26
23
  .filter((step) => step.nodeComponentPath)
@@ -57,7 +54,6 @@ async function importFlow(flow, flowConfig) {
57
54
  return { nodes, edges, nodeTypes };
58
55
  }
59
56
  export const useGetFlowState = (flow, flowConfig) => {
60
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
57
  const [nodeTypes, setNodeTypes] = useState(BASE_NODE_TYPES);
62
58
  const [nodes, setNodes, onNodesChange] = useNodesState([]);
63
59
  const [edges, setEdges, onEdgesChange] = useEdgesState([]);
@@ -1,2 +1,2 @@
1
- import { FlowConfigResponse } from '@/types/flow';
1
+ import type { FlowConfigResponse } from '@/types/flow';
2
2
  export declare const useSaveWorkflowConfig: () => (body: FlowConfigResponse) => Promise<any>;
@@ -1,6 +1,6 @@
1
- import { EdgeData, NodeData } from '@/types/flow';
2
- import { Edge, Node } from '@xyflow/react';
3
- import React from 'react';
1
+ import { type Edge, type Node } from '@xyflow/react';
2
+ import type React from 'react';
3
+ import type { EdgeData, NodeData } from '@/types/flow';
4
4
  type Props = {
5
5
  onInitialized: () => void;
6
6
  nodes: Node<NodeData>[];
@@ -1,2 +1,2 @@
1
- import { ApiNodeProps } from '@/publicComponents/node-props';
1
+ import type { ApiNodeProps } from '@/publicComponents/node-props';
2
2
  export declare const ApiFlowNode: ({ data }: ApiNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- import { CronNodeProps } from '@/publicComponents/node-props';
1
+ import type { CronNodeProps } from '@/publicComponents/node-props';
2
2
  export declare const CronFlowNode: ({ data }: CronNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- import { EventNodeProps } from '@/publicComponents/node-props';
1
+ import type { EventNodeProps } from '@/publicComponents/node-props';
2
2
  export declare const EventFlowNode: ({ data }: EventNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,2 +1,2 @@
1
- import { NoopNodeProps } from '@/publicComponents/node-props';
1
+ import type { NoopNodeProps } from '@/publicComponents/node-props';
2
2
  export declare const NoopFlowNode: ({ data }: NoopNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { analytics } from '@/lib/analytics';
3
2
  import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@motiadev/ui';
4
3
  import { Rocket } from 'lucide-react';
5
4
  import { useState } from 'react';
5
+ import { analytics } from '@/lib/analytics';
6
6
  export const DeployButton = () => {
7
7
  const [isOpen, setIsOpen] = useState(false);
8
8
  const onDeployButtonClick = () => {
@@ -24,5 +24,5 @@ export const DeployButton = () => {
24
24
  analytics.track('deploy_button_self_hosted_clicked');
25
25
  window.open('https://www.motia.dev/docs/deployment-guide/self-hosted', '_blank');
26
26
  };
27
- return (_jsxs(_Fragment, { children: [isOpen && (_jsxs("div", { children: [_jsx("div", { className: "fixed inset-0 z-[9999] bg-black/20 backdrop-blur-sm", onClick: () => setIsOpen(false) }), _jsxs("div", { className: "driver-popover w-[600px]! fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[10000] animate-in fade-in-0 zoom-in-95", children: [_jsx("img", { src: "https://oxhhfuuoqzsaqthfairn.supabase.co/storage/v1/object/public/public-images/preview.png", alt: "Motia Cloud", className: "driver-popover-image object-cover", style: { height: 393, width: '100%' } }), _jsx("div", { className: "driver-popover-title", children: _jsx("h2", { className: "popover-title", children: "Motia Cloud is Live!" }) }), _jsx("div", { className: "driver-popover-description", children: "Deploy to production in minutes, not hours. One click gets your Motia project live with enterprise-grade reliability. Seamlessly scale, rollback instantly, and monitor everything in real-time. Your code deserves infrastructure that just works." }), _jsx("a", { href: "https://www.motia.dev/docs/concepts/deployment/motia-cloud/features", target: "_blank", className: "text-foreground text-xs font-semibold px-4 hover:underline", children: "Learn more about Motia Cloud" }), _jsx("div", { className: "driver-popover-footer flex items-center justify-end", children: _jsxs("div", { className: "driver-popover-navigation-btns flex gap-6", children: [_jsx("button", { className: "tutorial-opt-out-button text-sm! font-semibold! text-muted-foreground!", onClick: onClose, children: "Close" }), _jsx("a", { href: "https://motia.cloud?utm_source=workbench&utm_medium=referral", target: "_blank", onClick: onDeployClick, children: _jsx("button", { className: "driver-popover-next-btn", children: "Deploy!" }) })] }) })] })] })), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", className: "font-semibold text-sm dark:bg-white dark:text-black dark:hover:bg-white/90 bg-black/90 hover:bg-black/80 text-white", onClick: onDeployButtonClick, children: [_jsx(Rocket, {}), "Deploy"] }) }), _jsxs(DropdownMenuContent, { className: "bg-background text-foreground w-56", children: [_jsx(DropdownMenuItem, { className: "cursor-pointer h-10 font-semibold", onClick: onMotiaCloudClick, children: "Motia Cloud" }), _jsx(DropdownMenuItem, { className: "cursor-pointer h-10 font-semibold", onClick: onSelfHostedClick, children: "Self-Hosted (Docker)" })] })] })] }));
27
+ return (_jsxs(_Fragment, { children: [isOpen && (_jsxs("div", { children: [_jsx("div", { className: "fixed inset-0 z-[9999] bg-black/20 backdrop-blur-sm", onClick: () => setIsOpen(false) }), _jsxs("div", { className: "driver-popover w-[600px]! fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-[10000] animate-in fade-in-0 zoom-in-95", children: [_jsx("img", { src: "https://oxhhfuuoqzsaqthfairn.supabase.co/storage/v1/object/public/public-images/preview.png", alt: "Motia Cloud", className: "driver-popover-image object-cover", style: { height: 393, width: '100%' } }), _jsx("div", { className: "driver-popover-title", children: _jsx("h2", { className: "popover-title", children: "Motia Cloud is Live!" }) }), _jsx("div", { className: "driver-popover-description", children: "Deploy to production in minutes, not hours. One click gets your Motia project live with enterprise-grade reliability. Seamlessly scale, rollback instantly, and monitor everything in real-time. Your code deserves infrastructure that just works." }), _jsx("a", { href: "https://www.motia.dev/docs/concepts/deployment/motia-cloud/features", target: "_blank", className: "text-foreground text-xs font-semibold px-4 hover:underline", rel: "noopener", children: "Learn more about Motia Cloud" }), _jsx("div", { className: "driver-popover-footer flex items-center justify-end", children: _jsxs("div", { className: "driver-popover-navigation-btns flex gap-6", children: [_jsx("button", { className: "tutorial-opt-out-button text-sm! font-semibold! text-muted-foreground!", onClick: onClose, children: "Close" }), _jsx("a", { href: "https://motia.cloud?utm_source=workbench&utm_medium=referral", target: "_blank", onClick: onDeployClick, rel: "noopener", children: _jsx("button", { className: "driver-popover-next-btn", children: "Deploy!" }) })] }) })] })] })), _jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs(Button, { variant: "ghost", className: "font-semibold text-sm dark:bg-white dark:text-black dark:hover:bg-white/90 bg-black/90 hover:bg-black/80 text-white", onClick: onDeployButtonClick, children: [_jsx(Rocket, {}), "Deploy"] }) }), _jsxs(DropdownMenuContent, { className: "bg-background text-foreground w-56", children: [_jsx(DropdownMenuItem, { className: "cursor-pointer h-10 font-semibold", onClick: onMotiaCloudClick, children: "Motia Cloud" }), _jsx(DropdownMenuItem, { className: "cursor-pointer h-10 font-semibold", onClick: onSelfHostedClick, children: "Self-Hosted (Docker)" })] })] })] }));
28
28
  };
@@ -1,2 +1,2 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  export declare const Header: React.FC;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import motiaLogoDark from '@/assets/motia-dark.png';
3
- import motiaLogoLight from '@/assets/motia-light.png';
4
2
  import { useThemeStore } from '@motiadev/ui';
5
3
  import { useEffect, useState } from 'react';
4
+ import motiaLogoDark from '@/assets/motia-dark.png';
5
+ import motiaLogoLight from '@/assets/motia-light.png';
6
6
  import { Tutorial } from '../tutorial/tutorial';
7
7
  import { TutorialButton } from '../tutorial/tutorial-button';
8
8
  import { ThemeToggle } from '../ui/theme-toggle';
@@ -1,2 +1,3 @@
1
- import React, { PropsWithChildren } from 'react';
1
+ import type React from 'react';
2
+ import type { PropsWithChildren } from 'react';
2
3
  export declare const RootMotia: React.FC<PropsWithChildren>;
@@ -1,4 +1,4 @@
1
- import { TutorialStep } from './tutorial-types';
1
+ import type { TutorialStep } from './tutorial-types';
2
2
  declare class Tutorial {
3
3
  steps: TutorialStep[];
4
4
  private onStepsRegisteredCallbacks;
@@ -1,4 +1,4 @@
1
- import { TutorialImage } from '../engine/tutorial-types';
1
+ import type { TutorialImage } from '../engine/tutorial-types';
2
2
  export declare const useTutorialEngine: () => {
3
3
  ref: import("react").RefObject<HTMLDivElement | null>;
4
4
  highlighterRef: import("react").RefObject<HTMLDivElement | null>;
@@ -1,4 +1,4 @@
1
- import { TutorialStep } from '../engine/tutorial-types';
1
+ import type { TutorialStep } from '../engine/tutorial-types';
2
2
  export declare const useTutorial: () => {
3
3
  open: () => void;
4
4
  steps: TutorialStep[];
@@ -1,2 +1,2 @@
1
- import { FC } from 'react';
1
+ import type { FC } from 'react';
2
2
  export declare const TutorialButton: FC;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { analytics } from '@/lib/analytics';
3
2
  import { Button } from '@motiadev/ui';
4
3
  import { Book } from 'lucide-react';
4
+ import { analytics } from '@/lib/analytics';
5
5
  import { Tooltip } from '../ui/tooltip';
6
6
  import { useTutorial } from './hooks/use-tutorial';
7
7
  export const TutorialButton = () => {
@@ -1,5 +1,5 @@
1
- import React from 'react';
2
- import { TutorialImage } from './engine/tutorial-types';
1
+ import type React from 'react';
2
+ import type { TutorialImage } from './engine/tutorial-types';
3
3
  type TutorialStepProps = {
4
4
  step: number;
5
5
  totalSteps: number;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { forwardRef, useEffect } from 'react';
3
2
  import { BackgroundEffect } from '@motiadev/ui';
3
+ import { forwardRef, useEffect } from 'react';
4
4
  export const TutorialStep = forwardRef(({ step, totalSteps, title, description, link, image, onNext, onClose }, ref) => {
5
5
  useEffect(() => {
6
6
  const handleKeyDown = (e) => {
@@ -1,6 +1,6 @@
1
- @import '@motiadev/ui/styles.css';
2
- @import '@motiadev/ui/globals.css';
3
- @import 'tw-animate-css';
1
+ @import "@motiadev/ui/styles.css";
2
+ @import "@motiadev/ui/globals.css";
3
+ @import "tw-animate-css";
4
4
 
5
5
  :root {
6
6
  --tutorial-text-color: var(--dark-800);
@@ -58,7 +58,6 @@
58
58
 
59
59
  .driver-popover-title {
60
60
  padding: 16px 16px 0 16px;
61
-
62
61
  }
63
62
 
64
63
  .driver-popover-description {
@@ -122,7 +121,7 @@
122
121
  }
123
122
 
124
123
  .driver-popover-navigation-btns-hint:hover:before {
125
- content: 'Use arrow keys to navigate';
124
+ content: "Use arrow keys to navigate";
126
125
  position: absolute;
127
126
  color: white;
128
127
  top: -20px;
@@ -155,7 +154,8 @@
155
154
  display: none;
156
155
  }
157
156
 
158
- .driver-popover-next-btn, .driver-popover-next-btn:hover {
157
+ .driver-popover-next-btn,
158
+ .driver-popover-next-btn:hover {
159
159
  color: white;
160
160
  padding: 16px 32px;
161
161
  }
@@ -201,7 +201,7 @@
201
201
  background: var(--tutorial-code-bg);
202
202
  padding: 16px;
203
203
  border-radius: 8px;
204
-
204
+
205
205
  code {
206
206
  font-size: 14px;
207
207
  font-weight: 400;
@@ -212,4 +212,4 @@
212
212
 
213
213
  .driver-popover-close-btn {
214
214
  display: none;
215
- }
215
+ }
@@ -1,4 +1,4 @@
1
- import { FC } from 'react';
1
+ import { type FC } from 'react';
2
2
  type JsonEditorProps = {
3
3
  value: string;
4
4
  height?: number | string;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useThemeStore } from '@motiadev/ui';
3
2
  import Editor, { useMonaco } from '@monaco-editor/react';
3
+ import { useThemeStore } from '@motiadev/ui';
4
4
  import { useEffect, useMemo } from 'react';
5
5
  export const JsonEditor = ({ value, height = 300, schema, onChange, onValidate, language = 'json', readOnly = false, }) => {
6
6
  const monaco = useMonaco();
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import * as React from 'react';
3
2
  import { cn } from '@motiadev/ui';
3
+ import * as React from 'react';
4
4
  const Table = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { className: "relative w-full overflow-auto", children: _jsx("table", { ref: ref, className: cn('w-full caption-bottom text-sm', className), ...props }) })));
5
5
  Table.displayName = 'Table';
6
6
  const TableHeader = React.forwardRef(({ className, ...props }, ref) => _jsx("thead", { ref: ref, className: cn('[&_tr]:border-b', className), ...props }));
@@ -1,2 +1,2 @@
1
- import React from 'react';
1
+ import type React from 'react';
2
2
  export declare const ThemeToggle: React.FC;
@@ -1,4 +1,4 @@
1
- import { ReactNode } from 'react';
1
+ import type { ReactNode } from 'react';
2
2
  export declare const Tooltip: ({ children, content, disabled, }: {
3
3
  children: ReactNode;
4
4
  content: string | ReactNode;
@@ -1,6 +1,6 @@
1
- import { useFlowStore } from '@/stores/use-flow-store';
2
1
  import { useStreamGroup } from '@motiadev/stream-client-react';
3
2
  import { useEffect } from 'react';
3
+ import { useFlowStore } from '@/stores/use-flow-store';
4
4
  export const useFetchFlows = () => {
5
5
  const setFlows = useFlowStore((state) => state.setFlows);
6
6
  const selectFlowId = useFlowStore((state) => state.selectFlowId);
@@ -1,5 +1,5 @@
1
1
  import { Position } from '@xyflow/react';
2
- import { BaseNodeProps } from '../publicComponents/node-props';
2
+ import type { BaseNodeProps } from '../publicComponents/node-props';
3
3
  export declare const useHandlePositions: (data: BaseNodeProps) => {
4
4
  sourcePosition: Position;
5
5
  targetPosition: Position;
@@ -1,7 +1,7 @@
1
- @import '@motiadev/ui/styles.css';
2
- @import '@motiadev/ui/globals.css';
1
+ @import "@motiadev/ui/styles.css";
2
+ @import "@motiadev/ui/globals.css";
3
3
 
4
- @import 'tw-animate-css';
4
+ @import "tw-animate-css";
5
5
  @config "../tailwind.config.js";
6
6
 
7
7
  @keyframes flowDash {
@@ -27,7 +27,7 @@
27
27
  }
28
28
 
29
29
  .font-mono {
30
- font-family: 'IBM Plex Mono', 'Courier New', monospace;
30
+ font-family: "IBM Plex Mono", "Courier New", monospace;
31
31
  font-size: 14px;
32
32
  }
33
33
 
@@ -40,7 +40,7 @@
40
40
  .json-view {
41
41
  border-radius: 8px;
42
42
  padding: 12px 12px;
43
- font-family: 'IBM Plex Mono', 'Courier New', monospace;
43
+ font-family: "IBM Plex Mono", "Courier New", monospace;
44
44
  font-size: 14px;
45
45
  line-height: 1.5;
46
46
  font-weight: 500;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { addAppTab, TabLocation } from '@/stores/use-app-tabs-store';
2
+ import { plugins } from 'virtual:motia-plugins';
3
3
  import { DynamicIcon, dynamicIconImports } from 'lucide-react/dynamic';
4
4
  import { memo } from 'react';
5
- import { plugins } from 'virtual:motia-plugins';
5
+ import { addAppTab, TabLocation } from '@/stores/use-app-tabs-store';
6
6
  import { isValidTabLocation } from './utils';
7
7
  export const registerPluginTabs = () => {
8
8
  if (!Array.isArray(plugins)) {
@@ -43,7 +43,7 @@ export const registerPluginTabs = () => {
43
43
  });
44
44
  PluginContent.displayName = `${plugin.label}Content`;
45
45
  addAppTab(tabLocation, {
46
- id: plugin.label,
46
+ id: plugin.label.toLowerCase(),
47
47
  tabLabel: PluginTabLabel,
48
48
  content: PluginContent,
49
49
  });
package/dist/src/main.js CHANGED
@@ -2,15 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { MotiaStreamProvider } from '@motiadev/stream-client-react';
3
3
  import { StrictMode } from 'react';
4
4
  import { createRoot } from 'react-dom/client';
5
- import { BrowserRouter, Routes, Route } from 'react-router-dom';
6
- import { RootMotia } from './components/root-motia';
5
+ import { BrowserRouter, Route, Routes } from 'react-router-dom';
7
6
  import { App } from './App';
8
7
  import { NotFoundPage } from './components/NotFoundPage';
8
+ import { RootMotia } from './components/root-motia';
9
9
  import '@motiadev/ui/globals.css';
10
10
  import './index.css';
11
11
  const rootElement = document.getElementById('root');
12
12
  if (!rootElement.innerHTML) {
13
- // eslint-disable-next-line no-undef
14
13
  const basePath = workbenchBase;
15
14
  const root = createRoot(rootElement);
16
15
  const address = window.location.origin.replace('http', 'ws');
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { TabLocation, useAppTabsStore } from './stores/use-app-tabs-store';
3
2
  import { APP_SIDEBAR_CONTAINER_ID, Panel } from '@motiadev/ui';
4
3
  import { useShallow } from 'zustand/react/shallow';
4
+ import { TabLocation, useAppTabsStore } from './stores/use-app-tabs-store';
5
5
  const topTabs = (state) => state.tabs[TabLocation.TOP];
6
6
  export const ProjectViewMode = () => {
7
7
  const tabs = useAppTabsStore(useShallow(topTabs));