@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,12 +0,0 @@
1
- import { type FC } from 'react';
2
- type JsonEditorProps = {
3
- value: string;
4
- height?: number | string;
5
- schema?: Record<string, unknown>;
6
- onChange?: (value: string) => void;
7
- onValidate?: (isValid: boolean) => void;
8
- language?: 'json' | string;
9
- readOnly?: boolean;
10
- };
11
- export declare const JsonEditor: FC<JsonEditorProps>;
12
- export {};
@@ -1,35 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import Editor, { useMonaco } from '@monaco-editor/react';
3
- import { useThemeStore } from '@motiadev/ui';
4
- import { useEffect, useMemo } from 'react';
5
- export const JsonEditor = ({ value, height = 300, schema, onChange, onValidate, language = 'json', readOnly = false, }) => {
6
- const monaco = useMonaco();
7
- const theme = useThemeStore((state) => state.theme);
8
- const editorTheme = useMemo(() => (theme === 'dark' ? 'vs-dark' : 'light'), [theme]);
9
- useEffect(() => {
10
- if (!monaco)
11
- return;
12
- monaco.languages.typescript.javascriptDefaults.setCompilerOptions({ isolatedModules: true });
13
- monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
14
- schemas: schema
15
- ? [
16
- {
17
- uri: window.location.href,
18
- fileMatch: ['*'],
19
- schema,
20
- },
21
- ]
22
- : [],
23
- });
24
- }, [monaco, schema, language]);
25
- return (_jsx(Editor, { "data-testid": "json-editor", height: height, language: language, value: value, theme: editorTheme, onChange: (value) => {
26
- if (!value) {
27
- onValidate?.(false);
28
- }
29
- onChange?.(value ?? '');
30
- }, onValidate: (markers) => onValidate?.(markers.length === 0), options: {
31
- readOnly,
32
- scrollBeyondLastLine: false,
33
- minimap: { enabled: false },
34
- } }));
35
- };
@@ -1,10 +0,0 @@
1
- import * as React from 'react';
2
- declare const Table: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
3
- declare const TableHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
4
- declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
5
- declare const TableFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
6
- declare const TableRow: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableRowElement> & React.RefAttributes<HTMLTableRowElement>>;
7
- declare const TableHead: React.ForwardRefExoticComponent<React.ThHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
8
- declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
9
- declare const TableCaption: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>>;
10
- export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
@@ -1,20 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from '@motiadev/ui';
3
- import * as React from 'react';
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
- Table.displayName = 'Table';
6
- const TableHeader = React.forwardRef(({ className, ...props }, ref) => _jsx("thead", { ref: ref, className: cn('[&_tr]:border-b', className), ...props }));
7
- TableHeader.displayName = 'TableHeader';
8
- const TableBody = React.forwardRef(({ className, ...props }, ref) => (_jsx("tbody", { ref: ref, className: cn('[&_tr:last-child]:border-0', className), ...props })));
9
- TableBody.displayName = 'TableBody';
10
- const TableFooter = React.forwardRef(({ className, ...props }, ref) => (_jsx("tfoot", { ref: ref, className: cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', className), ...props })));
11
- TableFooter.displayName = 'TableFooter';
12
- const TableRow = React.forwardRef(({ className, ...props }, ref) => (_jsx("tr", { ref: ref, className: cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', className), ...props })));
13
- TableRow.displayName = 'TableRow';
14
- const TableHead = React.forwardRef(({ className, ...props }, ref) => (_jsx("th", { ref: ref, className: cn('h-10 px-2 text-left align-middle text-md font-medium bg-muted text-muted-foreground font-bold [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', className), ...props })));
15
- TableHead.displayName = 'TableHead';
16
- const TableCell = React.forwardRef(({ className, ...props }, ref) => (_jsx("td", { ref: ref, className: cn('p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', className), ...props })));
17
- TableCell.displayName = 'TableCell';
18
- const TableCaption = React.forwardRef(({ className, ...props }, ref) => (_jsx("caption", { ref: ref, className: cn('mt-4 text-sm text-muted-foreground', className), ...props })));
19
- TableCaption.displayName = 'TableCaption';
20
- export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
@@ -1,2 +0,0 @@
1
- import type React from 'react';
2
- export declare const ThemeToggle: React.FC;
@@ -1,19 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn, useThemeStore } from '@motiadev/ui';
3
- import { Moon, Sun } from 'lucide-react';
4
- import { useEffect } from 'react';
5
- export const ThemeToggle = () => {
6
- const theme = useThemeStore((state) => state.theme);
7
- const setTheme = useThemeStore((state) => state.setTheme);
8
- const toggleTheme = () => {
9
- setTheme(theme === 'light' ? 'dark' : 'light');
10
- };
11
- useEffect(() => {
12
- const url = new URL(window.location.href);
13
- const colorScheme = url.searchParams.get('color-scheme');
14
- if (colorScheme) {
15
- setTheme(colorScheme);
16
- }
17
- }, [setTheme]);
18
- return (_jsxs("button", { onClick: toggleTheme, className: "relative flex items-center cursor-pointer w-16 h-8 border bg-muted-foreground/10 rounded-full p-1 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", "aria-label": `Switch to ${theme === 'light' ? 'dark' : 'light'} theme`, children: [_jsx("div", { className: cn('absolute w-6 h-6 bg-background border border-border rounded-full shadow-sm transition-transform duration-200 ease-in-out', theme === 'dark' ? 'translate-x-8' : 'translate-x-0') }), _jsx("div", { className: "flex items-center justify-center w-6 h-6 z-10", children: _jsx(Sun, { className: cn('h-3.5 w-3.5 transition-colors duration-200', theme === 'light' ? 'text-foreground' : 'text-muted-foreground') }) }), _jsx("div", { className: "flex items-center justify-center w-6 h-6 z-10 ml-2", children: _jsx(Moon, { className: cn('h-3.5 w-3.5 transition-colors duration-200', theme === 'dark' ? 'text-foreground' : 'text-muted-foreground') }) })] }));
19
- };
@@ -1,6 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- export declare const Tooltip: ({ children, content, disabled, }: {
3
- children: ReactNode;
4
- content: string | ReactNode;
5
- disabled?: boolean;
6
- }) => import("react/jsx-runtime").JSX.Element;
@@ -1,3 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import * as TooltipPrimitive from '@radix-ui/react-tooltip';
3
- export const Tooltip = ({ children, content, disabled, }) => (_jsx(TooltipPrimitive.Provider, { disableHoverableContent: disabled, children: _jsxs(TooltipPrimitive.Root, { children: [_jsx(TooltipPrimitive.Trigger, { asChild: true, children: children }), _jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, { className: "TooltipContent", side: "bottom", children: [_jsx("div", { className: "p-2 bg-background text-popover-foreground text-sm rounded-lg border border-light-800", children: content }), _jsx(TooltipPrimitive.Arrow, { className: "TooltipArrow" })] }) })] }) }));
@@ -1 +0,0 @@
1
- export declare const useDebounced: (fn: () => void, delay?: number) => () => void;
@@ -1,18 +0,0 @@
1
- import { useCallback, useEffect, useRef } from 'react';
2
- export const useDebounced = (fn, delay = 500) => {
3
- const saveTimeoutRef = useRef(null);
4
- const debouncedFn = useCallback(() => {
5
- if (saveTimeoutRef.current) {
6
- clearTimeout(saveTimeoutRef.current);
7
- }
8
- saveTimeoutRef.current = setTimeout(fn, delay);
9
- }, [fn, delay]);
10
- useEffect(() => {
11
- return () => {
12
- if (saveTimeoutRef.current) {
13
- clearTimeout(saveTimeoutRef.current);
14
- }
15
- };
16
- }, []);
17
- return debouncedFn;
18
- };
@@ -1 +0,0 @@
1
- export declare const useFetchFlows: () => void;
@@ -1,26 +0,0 @@
1
- import { useStreamGroup } from '@motiadev/stream-client-react';
2
- import { useEffect } from 'react';
3
- import { useFlowStore } from '@/stores/use-flow-store';
4
- const streamGroupArgs = { streamName: '__motia.flows', groupId: 'default' };
5
- export const useFetchFlows = () => {
6
- const setFlows = useFlowStore((state) => state.setFlows);
7
- const selectFlowId = useFlowStore((state) => state.selectFlowId);
8
- const clearSelectedFlowId = useFlowStore((state) => state.clearSelectedFlowId);
9
- const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
10
- const { data: flows } = useStreamGroup(streamGroupArgs);
11
- useEffect(() => {
12
- if (flows)
13
- setFlows(flows.map((flow) => flow.id));
14
- }, [flows, setFlows]);
15
- useEffect(() => {
16
- const hasFlows = flows.length > 0;
17
- const isSelectedFlowValid = selectedFlowId && flows.some((flow) => flow.id === selectedFlowId);
18
- if (!hasFlows && selectedFlowId) {
19
- clearSelectedFlowId();
20
- return;
21
- }
22
- if (hasFlows && (!selectedFlowId || !isSelectedFlowValid)) {
23
- selectFlowId(flows[0].id);
24
- }
25
- }, [flows, selectedFlowId, selectFlowId, clearSelectedFlowId]);
26
- };
@@ -1 +0,0 @@
1
- export declare function useIsMobile(): boolean;
@@ -1,15 +0,0 @@
1
- import * as React from 'react';
2
- const MOBILE_BREAKPOINT = 768;
3
- export function useIsMobile() {
4
- const [isMobile, setIsMobile] = React.useState(undefined);
5
- React.useEffect(() => {
6
- const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
7
- const onChange = () => {
8
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
9
- };
10
- mql.addEventListener('change', onChange);
11
- setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
12
- return () => mql.removeEventListener('change', onChange);
13
- }, []);
14
- return !!isMobile;
15
- }
@@ -1,10 +0,0 @@
1
- import { Position } from '@xyflow/react';
2
- import type { BaseNodeProps } from '../publicComponents/node-props';
3
- export declare const useHandlePositions: (data: BaseNodeProps) => {
4
- sourcePosition: Position;
5
- targetPosition: Position;
6
- updateSourcePosition: (position: "bottom" | "right") => void;
7
- updateTargetPosition: (position: "top" | "left") => void;
8
- toggleTargetPosition: () => void;
9
- toggleSourcePosition: () => void;
10
- };
@@ -1,35 +0,0 @@
1
- import { Position, useReactFlow, useUpdateNodeInternals } from '@xyflow/react';
2
- export const useHandlePositions = (data) => {
3
- const reactFlow = useReactFlow();
4
- const updateNodeInternals = useUpdateNodeInternals();
5
- const sourcePosition = data.nodeConfig?.sourceHandlePosition === 'bottom' ? Position.Bottom : Position.Right;
6
- const targetPosition = data.nodeConfig?.targetHandlePosition === 'top' ? Position.Top : Position.Left;
7
- const updateSourcePosition = (position) => {
8
- reactFlow.updateNode(data.id, {
9
- data: { ...data, nodeConfig: { ...data.nodeConfig, sourceHandlePosition: position } },
10
- });
11
- updateNodeInternals(data.id);
12
- };
13
- const updateTargetPosition = (position) => {
14
- reactFlow.updateNode(data.id, {
15
- data: { ...data, nodeConfig: { ...data.nodeConfig, targetHandlePosition: position } },
16
- });
17
- updateNodeInternals(data.id);
18
- };
19
- const toggleTargetPosition = () => {
20
- const newPosition = targetPosition === Position.Top ? Position.Left : Position.Top;
21
- updateTargetPosition(newPosition);
22
- };
23
- const toggleSourcePosition = () => {
24
- const newPosition = sourcePosition === Position.Bottom ? Position.Right : Position.Bottom;
25
- updateSourcePosition(newPosition);
26
- };
27
- return {
28
- sourcePosition,
29
- targetPosition,
30
- updateSourcePosition,
31
- updateTargetPosition,
32
- toggleTargetPosition,
33
- toggleSourcePosition,
34
- };
35
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,94 +0,0 @@
1
- import { formatDuration } from '../utils';
2
- describe('formatDuration', () => {
3
- describe('milliseconds', () => {
4
- it('should format values under 1 second as milliseconds', () => {
5
- expect(formatDuration(0)).toBe('0ms');
6
- expect(formatDuration(1)).toBe('1ms');
7
- expect(formatDuration(250)).toBe('250ms');
8
- expect(formatDuration(500)).toBe('500ms');
9
- expect(formatDuration(999)).toBe('999ms');
10
- });
11
- });
12
- describe('seconds', () => {
13
- it('should format values between 1 second and 1 minute as seconds with 1 decimal', () => {
14
- expect(formatDuration(1000)).toBe('1.0s');
15
- expect(formatDuration(1500)).toBe('1.5s');
16
- expect(formatDuration(15000)).toBe('15.0s');
17
- expect(formatDuration(45500)).toBe('45.5s');
18
- expect(formatDuration(59999)).toBe('60.0s');
19
- });
20
- it('should round to 1 decimal place', () => {
21
- expect(formatDuration(1234)).toBe('1.2s');
22
- expect(formatDuration(1567)).toBe('1.6s');
23
- expect(formatDuration(12345)).toBe('12.3s');
24
- });
25
- });
26
- describe('minutes', () => {
27
- it('should format values between 1 minute and 1 hour as minutes with 1 decimal', () => {
28
- expect(formatDuration(60000)).toBe('1.0min');
29
- expect(formatDuration(90000)).toBe('1.5min');
30
- expect(formatDuration(300000)).toBe('5.0min');
31
- expect(formatDuration(1800000)).toBe('30.0min');
32
- expect(formatDuration(3599999)).toBe('60.0min');
33
- });
34
- it('should round to 1 decimal place', () => {
35
- expect(formatDuration(123456)).toBe('2.1min');
36
- expect(formatDuration(567890)).toBe('9.5min');
37
- });
38
- });
39
- describe('hours', () => {
40
- it('should format values 1 hour or more as hours with 1 decimal', () => {
41
- expect(formatDuration(3600000)).toBe('1.0h');
42
- expect(formatDuration(5400000)).toBe('1.5h');
43
- expect(formatDuration(7200000)).toBe('2.0h');
44
- expect(formatDuration(36000000)).toBe('10.0h');
45
- });
46
- it('should round to 1 decimal place', () => {
47
- expect(formatDuration(3661000)).toBe('1.0h');
48
- expect(formatDuration(5432100)).toBe('1.5h');
49
- expect(formatDuration(9000000)).toBe('2.5h');
50
- });
51
- });
52
- describe('edge cases', () => {
53
- it('should return "N/A" for undefined', () => {
54
- expect(formatDuration(undefined)).toBe('N/A');
55
- });
56
- it('should return "N/A" for null', () => {
57
- expect(formatDuration(null)).toBe('N/A');
58
- });
59
- it('should return "N/A" for 0 when treated as falsy', () => {
60
- expect(formatDuration(0)).toBe('0ms');
61
- });
62
- });
63
- describe('boundary values', () => {
64
- it('should correctly handle millisecond-second boundary (999ms vs 1.0s)', () => {
65
- expect(formatDuration(999)).toBe('999ms');
66
- expect(formatDuration(1000)).toBe('1.0s');
67
- });
68
- it('should correctly handle second-minute boundary (59.9s vs 1.0min)', () => {
69
- expect(formatDuration(59999)).toBe('60.0s');
70
- expect(formatDuration(60000)).toBe('1.0min');
71
- });
72
- it('should correctly handle minute-hour boundary (59.9min vs 1.0h)', () => {
73
- expect(formatDuration(3599999)).toBe('60.0min');
74
- expect(formatDuration(3600000)).toBe('1.0h');
75
- });
76
- });
77
- describe('real-world scenarios', () => {
78
- it('should format typical API response times', () => {
79
- expect(formatDuration(50)).toBe('50ms');
80
- expect(formatDuration(150)).toBe('150ms');
81
- expect(formatDuration(2500)).toBe('2.5s');
82
- });
83
- it('should format typical workflow execution times', () => {
84
- expect(formatDuration(5000)).toBe('5.0s');
85
- expect(formatDuration(30000)).toBe('30.0s');
86
- expect(formatDuration(120000)).toBe('2.0min');
87
- });
88
- it('should format long-running tasks', () => {
89
- expect(formatDuration(600000)).toBe('10.0min');
90
- expect(formatDuration(1800000)).toBe('30.0min');
91
- expect(formatDuration(7200000)).toBe('2.0h');
92
- });
93
- });
94
- });
@@ -1,38 +0,0 @@
1
- interface AmplitudeInstance {
2
- setOptOut(optOut: boolean): void;
3
- track(eventName: string, eventProperties?: Record<string, any>): void;
4
- identify(userId: string, userProperties?: Record<string, any>): void;
5
- setUserId(userId: string): void;
6
- getUserId(): string | undefined;
7
- }
8
- declare global {
9
- interface Window {
10
- amplitude: AmplitudeInstance;
11
- }
12
- }
13
- declare class WorkbenchAnalytics {
14
- private isInitialized;
15
- private userIdCache;
16
- private projectIdCache;
17
- private motiaVersion;
18
- constructor();
19
- private initialize;
20
- private fetchUserData;
21
- private generateFallbackUserId;
22
- private identifyUser;
23
- private getBrowserInfo;
24
- getAnalyticsIds(): {
25
- userId: string | null;
26
- projectId: string | null;
27
- };
28
- track(eventName: string, properties?: Record<string, any>): void;
29
- }
30
- export declare const motiaAnalytics: WorkbenchAnalytics;
31
- export declare const useAnalytics: () => {
32
- track: (eventName: string, properties?: Record<string, any>) => void;
33
- getAnalyticsIds: () => {
34
- userId: string | null;
35
- projectId: string | null;
36
- };
37
- };
38
- export {};
@@ -1,132 +0,0 @@
1
- import { useCallback } from 'react';
2
- class WorkbenchAnalytics {
3
- constructor() {
4
- Object.defineProperty(this, "isInitialized", {
5
- enumerable: true,
6
- configurable: true,
7
- writable: true,
8
- value: false
9
- });
10
- Object.defineProperty(this, "userIdCache", {
11
- enumerable: true,
12
- configurable: true,
13
- writable: true,
14
- value: null
15
- });
16
- Object.defineProperty(this, "projectIdCache", {
17
- enumerable: true,
18
- configurable: true,
19
- writable: true,
20
- value: null
21
- });
22
- Object.defineProperty(this, "motiaVersion", {
23
- enumerable: true,
24
- configurable: true,
25
- writable: true,
26
- value: null
27
- });
28
- this.initialize();
29
- }
30
- async initialize() {
31
- if (typeof window !== 'undefined' && window.amplitude) {
32
- await this.fetchUserData();
33
- this.isInitialized = true;
34
- this.identifyUser();
35
- }
36
- }
37
- async fetchUserData() {
38
- try {
39
- const response = await fetch('/motia/analytics/user');
40
- if (response.ok) {
41
- const data = await response.json();
42
- this.userIdCache = data.userId;
43
- this.projectIdCache = data.projectId;
44
- this.motiaVersion = data.motiaVersion;
45
- window.amplitude.setOptOut(!data.analyticsEnabled);
46
- // Set the user ID in Amplitude to match backend
47
- if (window.amplitude && data.userId) {
48
- window.amplitude.setUserId(data.userId);
49
- }
50
- }
51
- else {
52
- console.warn('Failed to fetch user data from backend, using fallback');
53
- this.userIdCache = this.generateFallbackUserId();
54
- }
55
- }
56
- catch (error) {
57
- console.warn('Error fetching user data:', error);
58
- this.userIdCache = this.generateFallbackUserId();
59
- }
60
- }
61
- generateFallbackUserId() {
62
- let userId = localStorage.getItem('motia-user-id');
63
- if (!userId) {
64
- userId = `user-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
65
- localStorage.setItem('motia-user-id', userId);
66
- }
67
- return userId;
68
- }
69
- identifyUser() {
70
- if (!this.isInitialized || !this.userIdCache)
71
- return;
72
- try {
73
- window.amplitude.identify(this.userIdCache, {
74
- project_id: this.projectIdCache,
75
- browser: this.getBrowserInfo(),
76
- screen_resolution: `${window.screen.width}x${window.screen.height}`,
77
- workbench_version: this.motiaVersion,
78
- });
79
- }
80
- catch (error) {
81
- console.warn('Analytics user identification failed:', error);
82
- }
83
- }
84
- getBrowserInfo() {
85
- const ua = navigator.userAgent;
86
- if (ua.includes('Chrome'))
87
- return 'Chrome';
88
- if (ua.includes('Firefox'))
89
- return 'Firefox';
90
- if (ua.includes('Safari'))
91
- return 'Safari';
92
- if (ua.includes('Edge'))
93
- return 'Edge';
94
- return 'Unknown';
95
- }
96
- // Method to get current user and project IDs for external use
97
- getAnalyticsIds() {
98
- return {
99
- userId: this.userIdCache,
100
- projectId: this.projectIdCache,
101
- };
102
- }
103
- // Simple track method that preserves the user binding
104
- track(eventName, properties) {
105
- if (!this.isInitialized)
106
- return;
107
- const eventProperties = {
108
- project_id: this.projectIdCache,
109
- source: 'frontend',
110
- ...properties,
111
- };
112
- try {
113
- window.amplitude.track(eventName, eventProperties);
114
- }
115
- catch (error) {
116
- console.warn('Analytics tracking failed:', error);
117
- }
118
- }
119
- }
120
- export const motiaAnalytics = new WorkbenchAnalytics();
121
- export const useAnalytics = () => {
122
- const track = useCallback((eventName, properties) => {
123
- motiaAnalytics.track(eventName, properties);
124
- }, []);
125
- const getAnalyticsIds = useCallback(() => {
126
- return motiaAnalytics.getAnalyticsIds();
127
- }, []);
128
- return {
129
- track,
130
- getAnalyticsIds,
131
- };
132
- };
@@ -1,2 +0,0 @@
1
- import { type AppTab, TabLocation } from '@/stores/use-app-tabs-store';
2
- export declare const registerPluginTabs: (addTab: (position: TabLocation, tab: AppTab) => void) => void;
@@ -1,105 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { plugins } from 'virtual:motia-plugins';
3
- import { DynamicIcon, dynamicIconImports } from 'lucide-react/dynamic';
4
- import { memo } from 'react';
5
- import { TabLocation, useAppTabsStore } from '@/stores/use-app-tabs-store';
6
- import { isValidTabLocation } from './utils';
7
- export const registerPluginTabs = (addTab) => {
8
- if (!Array.isArray(plugins)) {
9
- console.warn('[Motia] Invalid plugins configuration: expected array');
10
- return;
11
- }
12
- plugins.forEach((plugin, index) => {
13
- try {
14
- if (!plugin.label) {
15
- console.warn(`[Motia] Plugin at index ${index} missing label, skipping`);
16
- return;
17
- }
18
- if (!plugin.component) {
19
- console.warn(`[Motia] Plugin "${plugin.label}" missing component, skipping`);
20
- return;
21
- }
22
- const position = plugin.position || 'top';
23
- if (!isValidTabLocation(position)) {
24
- console.warn(`[Motia] Plugin "${plugin.label}" has invalid position "${position}", defaulting to "top"`);
25
- }
26
- const tabLocation = isValidTabLocation(position) ? position : TabLocation.TOP;
27
- const PluginTabLabel = memo(() => {
28
- const hasIcon = Object.keys(dynamicIconImports).includes(plugin.labelIcon);
29
- const iconName = hasIcon ? plugin.labelIcon : 'toy-brick';
30
- if (!hasIcon) {
31
- console.warn(`[Motia] Plugin "${plugin.label}" has invalid icon "${plugin.labelIcon}", defaulting to "toy-brick"`);
32
- }
33
- return (_jsxs(_Fragment, { children: [_jsx(DynamicIcon, { name: iconName }), _jsx("span", { children: plugin.label })] }));
34
- });
35
- PluginTabLabel.displayName = `${plugin.label}TabLabel`;
36
- const PluginContent = memo(() => {
37
- const Component = plugin.component;
38
- const props = plugin.props || {};
39
- if (!Component) {
40
- return _jsx("div", { children: "Error: Plugin component not found" });
41
- }
42
- return _jsx(Component, { ...props });
43
- });
44
- PluginContent.displayName = `${plugin.label}Content`;
45
- addTab(tabLocation, {
46
- id: plugin.label.toLowerCase(),
47
- tabLabel: PluginTabLabel,
48
- content: PluginContent,
49
- });
50
- }
51
- catch (error) {
52
- console.error(`[Motia] Error registering plugin "${plugin.label}":`, error);
53
- }
54
- });
55
- };
56
- const refreshPluginTabs = (nextPlugins) => {
57
- try {
58
- const state = useAppTabsStore.getState();
59
- const { removeTab, addTab } = state;
60
- const idsToRefresh = new Set(nextPlugins.map((p) => (p.label || '').toLowerCase()));
61
- idsToRefresh.forEach((id) => {
62
- removeTab(TabLocation.TOP, id);
63
- removeTab(TabLocation.BOTTOM, id);
64
- });
65
- nextPlugins.forEach((plugin, index) => {
66
- try {
67
- if (!plugin.label || !plugin.component)
68
- return;
69
- const position = plugin.position || 'top';
70
- const tabLocation = isValidTabLocation(position) ? position : TabLocation.TOP;
71
- const PluginTabLabel = memo(() => {
72
- const hasIcon = Object.keys(dynamicIconImports).includes(plugin.labelIcon);
73
- const iconName = hasIcon ? plugin.labelIcon : 'toy-brick';
74
- return (_jsxs(_Fragment, { children: [_jsx(DynamicIcon, { name: iconName }), _jsx("span", { children: plugin.label })] }));
75
- });
76
- PluginTabLabel.displayName = `${plugin.label}TabLabel_HMR_${index}`;
77
- const PluginContent = memo(() => {
78
- const Component = plugin.component;
79
- const props = plugin.props || {};
80
- if (!Component)
81
- return _jsx("div", { children: "Error: Plugin component not found" });
82
- return _jsx(Component, { ...props });
83
- });
84
- PluginContent.displayName = `${plugin.label}Content_HMR_${index}`;
85
- addTab(tabLocation, {
86
- id: plugin.label.toLowerCase(),
87
- tabLabel: PluginTabLabel,
88
- content: PluginContent,
89
- });
90
- }
91
- catch (error) {
92
- console.error(`[Motia] Error refreshing plugin "${plugin.label}":`, error);
93
- }
94
- });
95
- }
96
- catch (err) {
97
- console.error('[Motia] Failed to refresh plugin tabs via HMR:', err);
98
- }
99
- };
100
- if (import.meta.hot) {
101
- import.meta.hot.accept('virtual:motia-plugins', (mod) => {
102
- const next = mod?.plugins || [];
103
- refreshPluginTabs(next);
104
- });
105
- }
@@ -1,7 +0,0 @@
1
- import { TabLocation } from '@/stores/use-app-tabs-store';
2
- export declare const formatDuration: (duration?: number) => string;
3
- export declare const formatTimestamp: (time: number) => string;
4
- export type ViewMode = 'project' | 'system';
5
- export declare const DEFAULT_VIEW_MODE: ViewMode;
6
- export declare const getViewModeFromURL: () => ViewMode;
7
- export declare const isValidTabLocation: (position: string) => position is TabLocation;