@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,2 +0,0 @@
1
- import type { CronNodeProps } from '@/publicComponents/node-props';
2
- export declare const CronFlowNode: ({ data }: CronNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { CronNode } from '@/publicComponents/cron-node';
3
- export const CronFlowNode = ({ data }) => {
4
- return _jsx(CronNode, { data: data });
5
- };
@@ -1,2 +0,0 @@
1
- import type { EventNodeProps } from '@/publicComponents/node-props';
2
- export declare const EventFlowNode: ({ data }: EventNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { EventNode } from '@/publicComponents/event-node';
3
- export const EventFlowNode = ({ data }) => {
4
- return _jsx(EventNode, { data: data });
5
- };
@@ -1,2 +0,0 @@
1
- import type { NoopNodeProps } from '@/publicComponents/node-props';
2
- export declare const NoopFlowNode: ({ data }: NoopNodeProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { NoopNode } from '@/publicComponents/noop-node';
3
- export const NoopFlowNode = ({ data }) => {
4
- return _jsx(NoopNode, { data: data });
5
- };
@@ -1 +0,0 @@
1
- export declare const DeployButton: () => import("react/jsx-runtime").JSX.Element;
@@ -1,28 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@motiadev/ui';
3
- import { Rocket } from 'lucide-react';
4
- import { useState } from 'react';
5
- import { motiaAnalytics } from '@/lib/motia-analytics';
6
- export const DeployButton = () => {
7
- const [isOpen, setIsOpen] = useState(false);
8
- const onDeployButtonClick = () => {
9
- motiaAnalytics.track('deploy_button_clicked');
10
- };
11
- const onDeployClick = () => {
12
- setIsOpen(false);
13
- motiaAnalytics.track('deploy_button_deploy_clicked');
14
- };
15
- const onClose = () => {
16
- setIsOpen(false);
17
- motiaAnalytics.track('deploy_button_closed');
18
- };
19
- const onMotiaCloudClick = () => {
20
- setIsOpen(true);
21
- motiaAnalytics.track('deploy_button_motia_cloud_clicked');
22
- };
23
- const onSelfHostedClick = () => {
24
- motiaAnalytics.track('deploy_button_self_hosted_clicked');
25
- window.open('https://www.motia.dev/docs/deployment-guide/self-hosted', '_blank');
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/deployment-guide/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
- };
@@ -1,2 +0,0 @@
1
- import type React from 'react';
2
- export declare const Header: React.FC;
@@ -1,23 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useThemeStore } from '@motiadev/ui';
3
- import { memo, useEffect } from 'react';
4
- import motiaLogoDark from '@/assets/motia-dark.png';
5
- import motiaLogoLight from '@/assets/motia-light.png';
6
- import { useMotiaConfigStore } from '@/stores/use-motia-config-store';
7
- import { Tutorial } from '../tutorial/tutorial';
8
- import { TutorialButton } from '../tutorial/tutorial-button';
9
- import { ThemeToggle } from '../ui/theme-toggle';
10
- import { DeployButton } from './deploy-button';
11
- export const Header = memo(() => {
12
- const theme = useThemeStore((state) => state.theme);
13
- const logo = theme === 'light' ? motiaLogoLight : motiaLogoDark;
14
- const config = useMotiaConfigStore((state) => state.config);
15
- const fetchConfig = useMotiaConfigStore((state) => state.fetchConfig);
16
- useEffect(() => {
17
- fetchConfig();
18
- }, []);
19
- const isDevMode = config?.isDev ?? false;
20
- const isTutorialDisabled = config?.isTutorialDisabled ?? true;
21
- return (_jsxs("header", { className: "min-h-16 px-4 gap-4 flex items-center bg-default text-default-foreground border-b", children: [_jsx("img", { src: logo, className: "h-5", id: "logo-icon", "data-testid": "logo-icon" }), _jsx("div", { className: "flex-1" }), _jsx(ThemeToggle, {}), isDevMode && !isTutorialDisabled && _jsx(TutorialButton, {}), isDevMode && _jsx(DeployButton, {}), !isTutorialDisabled && _jsx(Tutorial, {})] }));
22
- });
23
- Header.displayName = 'Header';
@@ -1,2 +0,0 @@
1
- import type { PropsWithChildren } from 'react';
2
- export declare const RootMotia: React.FC<PropsWithChildren>;
@@ -1,7 +0,0 @@
1
- import { memo } from 'react';
2
- import { useAnalytics } from '@/lib/motia-analytics';
3
- export const RootMotia = memo(({ children }) => {
4
- useAnalytics();
5
- return children;
6
- });
7
- RootMotia.displayName = 'RootMotia';
@@ -1 +0,0 @@
1
- export declare const TopPanel: 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 topTabsSelector = (state) => state.tabs[TabLocation.TOP];
8
- const topPanelId = 'top-panel';
9
- export const TopPanel = memo(() => {
10
- const defaultTab = useTabsStore((state) => state.tab.top);
11
- const setTopTab = useTabsStore((state) => state.setTopTab);
12
- const tabs = useAppTabsStore(useShallow(topTabsSelector));
13
- return (_jsx(CollapsiblePanel, { id: topPanelId, variant: 'tabs', defaultTab: defaultTab, onTabChange: setTopTab, withResizeHandle: true, 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
- TopPanel.displayName = 'TopPanel';
@@ -1,12 +0,0 @@
1
- import type { TutorialStep } from './tutorial-types';
2
- declare class Tutorial {
3
- steps: TutorialStep[];
4
- private onStepsRegisteredCallbacks;
5
- private onOpenCallbacks;
6
- register(steps: TutorialStep[]): void;
7
- onStepsRegistered(callback: () => void): void;
8
- onOpen(callback: () => void): void;
9
- open(): void;
10
- }
11
- export declare const MotiaTutorial: Tutorial;
12
- export {};
@@ -1,36 +0,0 @@
1
- class Tutorial {
2
- constructor() {
3
- Object.defineProperty(this, "steps", {
4
- enumerable: true,
5
- configurable: true,
6
- writable: true,
7
- value: []
8
- });
9
- Object.defineProperty(this, "onStepsRegisteredCallbacks", {
10
- enumerable: true,
11
- configurable: true,
12
- writable: true,
13
- value: []
14
- });
15
- Object.defineProperty(this, "onOpenCallbacks", {
16
- enumerable: true,
17
- configurable: true,
18
- writable: true,
19
- value: []
20
- });
21
- }
22
- register(steps) {
23
- this.steps = steps;
24
- this.onStepsRegisteredCallbacks.forEach((callback) => callback());
25
- }
26
- onStepsRegistered(callback) {
27
- this.onStepsRegisteredCallbacks.push(callback);
28
- }
29
- onOpen(callback) {
30
- this.onOpenCallbacks.push(callback);
31
- }
32
- open() {
33
- this.onOpenCallbacks.forEach((callback) => callback());
34
- }
35
- }
36
- export const MotiaTutorial = new Tutorial();
@@ -1,22 +0,0 @@
1
- export type TutorialActionClick = {
2
- type: 'click';
3
- selector: string;
4
- optional?: boolean;
5
- };
6
- export type TutorialActionEditor = {
7
- type: 'fill-editor';
8
- content: Record<string, any>;
9
- };
10
- export type TutorialAction = TutorialActionClick | TutorialActionEditor;
11
- export type TutorialImage = {
12
- height: number;
13
- src: string;
14
- };
15
- export type TutorialStep = {
16
- title: string;
17
- description: React.FC<void>;
18
- image?: TutorialImage;
19
- link?: string;
20
- elementXpath?: string;
21
- before?: TutorialAction[];
22
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,45 +0,0 @@
1
- export declare const workbenchXPath: {
2
- sidebarContainer: string;
3
- closePanelButton: string;
4
- bottomPanel: string;
5
- flows: {
6
- dropdownFlow: (flowId: string) => string;
7
- feature: (featureId: string) => string;
8
- previewButton: (stepId: string) => string;
9
- node: (stepId: string) => string;
10
- };
11
- endpoints: {
12
- endpointsList: string;
13
- endpoint: (method: string, path: string) => string;
14
- callPanel: string;
15
- specButton: string;
16
- bodyTab: string;
17
- headersTab: string;
18
- paramsTab: string;
19
- callTab: string;
20
- response: string;
21
- playButton: string;
22
- };
23
- tracing: {
24
- trace: (index: number) => string;
25
- details: string;
26
- timeline: (index: number) => string;
27
- };
28
- logs: {
29
- container: string;
30
- searchContainer: string;
31
- traceColumn: (index: number) => string;
32
- row: string;
33
- };
34
- states: {
35
- container: string;
36
- row: (index: number) => string;
37
- };
38
- links: {
39
- flows: string;
40
- endpoints: string;
41
- tracing: string;
42
- logs: string;
43
- states: string;
44
- };
45
- };
@@ -1,45 +0,0 @@
1
- export const workbenchXPath = {
2
- sidebarContainer: '//div[@data-testid="sidebar-panel"]',
3
- closePanelButton: '//div[@id="app-sidebar-container"]//button[@data-testid="close-panel"]',
4
- bottomPanel: '//div[@id="bottom-panel"]',
5
- flows: {
6
- dropdownFlow: (flowId) => `//div[@data-testid="dropdown-${flowId}"]`,
7
- feature: (featureId) => `//div[@data-feature-id="${featureId}"]`,
8
- previewButton: (stepId) => `//button[@data-testid="open-code-preview-button-${stepId}"]`,
9
- node: (stepId) => `//div[@data-testid="node-${stepId}"]`,
10
- },
11
- endpoints: {
12
- endpointsList: '//div[@data-testid="endpoints-list"]',
13
- endpoint: (method, path) => `//div[@data-testid="endpoint-${method}-${path}"]`,
14
- callPanel: '//div[@data-testid="endpoint-details-panel"]',
15
- specButton: '//button[@data-testid="endpoint-spec-button"]',
16
- bodyTab: '//button[@data-testid="endpoint-body-tab"]',
17
- headersTab: '//button[@data-testid="endpoint-headers-tab"]',
18
- paramsTab: '//button[@data-testid="endpoint-params-tab"]',
19
- callTab: '//button[@data-testid="endpoint-body-tab"]', // deprecated
20
- response: '//div[@data-testid="endpoint-response-container"]',
21
- playButton: '//button[@data-testid="endpoint-play-button"]',
22
- },
23
- tracing: {
24
- trace: (index) => `(//button[contains(@class, 'motia-trace-group')])[${index}]`,
25
- details: '//div[@data-testid="trace-details"]',
26
- timeline: (index) => `(//div[@data-testid="trace-timeline-item"])[${index}]`,
27
- },
28
- logs: {
29
- container: '//div[@data-testid="logs-container"]',
30
- searchContainer: '//div[@data-testid="logs-search-container"]',
31
- traceColumn: (index) => `(//td[starts-with(@data-testid, 'trace')])[${index}]`,
32
- row: '//div[@data-testid="log-row"]',
33
- },
34
- states: {
35
- container: '//div[@data-testid="states-container"]',
36
- row: (index) => `(//tr[starts-with(@data-testid, 'item-')])[${index}]`,
37
- },
38
- links: {
39
- flows: '//div[@data-testid="flows-dropdown-trigger"]',
40
- endpoints: '//button[@data-testid="endpoints-link"]',
41
- tracing: '//button[@data-testid="tracing-link"]',
42
- logs: '//button[@data-testid="logs-link"]',
43
- states: '//button[@data-testid="states-link"]',
44
- },
45
- };
@@ -1 +0,0 @@
1
- export declare const waitForElementByXPath: (xpath: string, optional?: boolean, maxAttempts?: number, delayMs?: number) => Promise<HTMLElement | null>;
@@ -1,17 +0,0 @@
1
- export const waitForElementByXPath = async (xpath, optional = false, maxAttempts = 50, delayMs = 50) => {
2
- let attempts = 0;
3
- while (attempts < maxAttempts) {
4
- const result = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
5
- const targetElement = result?.singleNodeValue;
6
- if (targetElement) {
7
- return targetElement;
8
- }
9
- else if (optional) {
10
- return null;
11
- }
12
- await new Promise((resolve) => setTimeout(resolve, delayMs));
13
- attempts++;
14
- }
15
- console.warn(`Element not found after maximum attempts: ${xpath}`);
16
- return null;
17
- };
@@ -1,15 +0,0 @@
1
- import type { TutorialImage } from '../engine/tutorial-types';
2
- export declare const useTutorialEngine: () => {
3
- ref: import("react").RefObject<HTMLDivElement | null>;
4
- highlighterRef: import("react").RefObject<HTMLDivElement | null>;
5
- title: string;
6
- description: import("react").ReactNode;
7
- image: TutorialImage | undefined;
8
- link: string | undefined;
9
- currentStep: number;
10
- totalSteps: number;
11
- onClose: () => void;
12
- moveStep: (stepNumber: number) => Promise<void>;
13
- currentStepRef: import("react").RefObject<number>;
14
- manualOpenRef: import("react").RefObject<boolean>;
15
- };
@@ -1,183 +0,0 @@
1
- import { useEffect, useRef, useState } from 'react';
2
- import { MotiaTutorial } from '../engine/tutorial-engine';
3
- import { waitForElementByXPath } from './tutorial-utils';
4
- export const useTutorialEngine = () => {
5
- const ref = useRef(null);
6
- const highlighterRef = useRef(null);
7
- const [title, setTitle] = useState('');
8
- const [description, setDescription] = useState(undefined);
9
- const [image, setImage] = useState(undefined);
10
- const [link, setLink] = useState(undefined);
11
- const [currentStep, setCurrentStep] = useState(0);
12
- const [totalSteps, setTotalSteps] = useState(MotiaTutorial.steps.length);
13
- const manualOpenRef = useRef(false);
14
- const loading = useRef(false);
15
- const currentStepRef = useRef(0);
16
- const moveComponent = (x, y) => {
17
- if (ref.current) {
18
- ref.current.style.position = 'absolute';
19
- ref.current.style.left = `${x}px`;
20
- ref.current.style.top = `${y}px`;
21
- }
22
- };
23
- const moveStep = async (stepNumber) => {
24
- const container = ref.current;
25
- if (container && !loading.current) {
26
- if (stepNumber >= MotiaTutorial.steps.length) {
27
- onClose();
28
- return;
29
- }
30
- if (container.parentElement) {
31
- container.style.transition = 'all 0.3s ease-in-out';
32
- container.parentElement.style.opacity = '1';
33
- container.parentElement.style.display = 'block';
34
- }
35
- loading.current = true;
36
- currentStepRef.current = stepNumber;
37
- const step = MotiaTutorial.steps[stepNumber];
38
- // Run any before actions
39
- if (step.before) {
40
- for (const action of step.before) {
41
- const monaco = window.monaco;
42
- if (action.type === 'click') {
43
- const element = await waitForElementByXPath(action.selector, action.optional);
44
- if (element) {
45
- element.scrollIntoView({ behavior: 'smooth', block: 'center' });
46
- element.click();
47
- element.dispatchEvent(new KeyboardEvent('keydown', { bubbles: true, cancelable: true, key: 'Enter', keyCode: 13 }));
48
- }
49
- }
50
- else if (action.type === 'fill-editor' && monaco) {
51
- monaco.editor?.getEditors?.()?.[0]?.setValue(JSON.stringify(action.content, null, 2));
52
- }
53
- }
54
- }
55
- setCurrentStep(stepNumber + 1);
56
- setTitle(step.title);
57
- setDescription(await step.description());
58
- setImage(step.image);
59
- setLink(step.link);
60
- setTimeout(async () => {
61
- const { height, width } = container.getBoundingClientRect();
62
- if (step.elementXpath) {
63
- const targetElement = await waitForElementByXPath(step.elementXpath);
64
- if (!targetElement) {
65
- console.warn(`Element not found after maximum attempts: ${step.elementXpath}`);
66
- loading.current = false;
67
- return;
68
- }
69
- if (targetElement && highlighterRef.current) {
70
- const { top, left, width, height } = targetElement.getBoundingClientRect();
71
- highlighterRef.current.style.top = `${top - 0}px`;
72
- highlighterRef.current.style.left = `${left - 0}px`;
73
- highlighterRef.current.style.width = `${width + 0}px`;
74
- highlighterRef.current.style.height = `${height + 0}px`;
75
- }
76
- // Position tutorial relative to target element
77
- if (targetElement) {
78
- const targetRect = targetElement.getBoundingClientRect();
79
- const spaceBelow = window.innerHeight - targetRect.bottom;
80
- const spaceAbove = targetRect.top;
81
- const spaceRight = window.innerWidth - targetRect.right;
82
- const spaceLeft = targetRect.left;
83
- // Helper function to adjust horizontal position within viewport bounds
84
- const adjustHorizontalPosition = (x) => {
85
- // this is important to avoid the tutorial from overflowing at far left or right
86
- return Math.max(20, Math.min(x, window.innerWidth - width - 20));
87
- };
88
- // Try to position below first
89
- if (spaceBelow >= height + 20) {
90
- const x = targetRect.left + targetRect.width / 2 - width / 2;
91
- moveComponent(adjustHorizontalPosition(x), targetRect.bottom + 20);
92
- }
93
- // Try above if not enough space below
94
- else if (spaceAbove >= height + 20) {
95
- const x = targetRect.left + targetRect.width / 2 - width / 2;
96
- moveComponent(adjustHorizontalPosition(x), targetRect.top - height - 20);
97
- }
98
- // Try right side
99
- else if (spaceRight >= width + 20) {
100
- moveComponent(targetRect.right + 20, targetRect.top + targetRect.height / 2 - height / 2);
101
- }
102
- // Try left side
103
- else if (spaceLeft >= width + 20) {
104
- moveComponent(targetRect.left - width - 20, targetRect.top + targetRect.height / 2 - height / 2);
105
- }
106
- }
107
- }
108
- else {
109
- if (highlighterRef.current) {
110
- highlighterRef.current.style.top = '50%';
111
- highlighterRef.current.style.left = '50%';
112
- highlighterRef.current.style.width = '1px';
113
- highlighterRef.current.style.height = '1px';
114
- }
115
- // Fallback to center of screen
116
- moveComponent(window.innerWidth / 2 - width / 2, window.innerHeight / 2 - height / 2);
117
- }
118
- }, 1);
119
- loading.current = false;
120
- }
121
- };
122
- const onClose = () => {
123
- if (ref.current?.parentElement) {
124
- ref.current.parentElement.style.transition = 'opacity 0.3s ease-out';
125
- ref.current.parentElement.style.opacity = '0';
126
- localStorage.setItem('motia-tutorial-closed', 'true');
127
- setTimeout(() => {
128
- if (ref.current?.parentElement) {
129
- ref.current.parentElement.style.display = 'none';
130
- setCurrentStep(0);
131
- }
132
- }, 300);
133
- }
134
- };
135
- useEffect(() => {
136
- importFile('tutorial/tutorial.tsx')
137
- .then((module) => {
138
- if (Array.isArray(module.steps) && module.steps.length > 0) {
139
- MotiaTutorial.register(module.steps);
140
- }
141
- })
142
- .catch((error) => {
143
- // Tutorial file is optional, so we don't need to throw an error
144
- console.log('Tutorial file not found or could not be loaded:', error.message);
145
- });
146
- }, []);
147
- useEffect(() => {
148
- const container = ref.current;
149
- if (container?.parentElement) {
150
- container.parentElement.style.display = 'none';
151
- }
152
- const onOpen = () => {
153
- if (container?.parentElement) {
154
- setTotalSteps(MotiaTutorial.steps.length);
155
- moveStep(0);
156
- }
157
- };
158
- MotiaTutorial.onOpen(() => {
159
- manualOpenRef.current = true;
160
- onOpen();
161
- });
162
- MotiaTutorial.onStepsRegistered(() => {
163
- if (localStorage.getItem('motia-tutorial-closed') !== 'true') {
164
- manualOpenRef.current = false;
165
- onOpen();
166
- }
167
- });
168
- }, []);
169
- return {
170
- ref,
171
- highlighterRef,
172
- title,
173
- description,
174
- image,
175
- link,
176
- currentStep,
177
- totalSteps,
178
- onClose,
179
- moveStep,
180
- currentStepRef,
181
- manualOpenRef,
182
- };
183
- };
@@ -1,5 +0,0 @@
1
- import type { TutorialStep } from '../engine/tutorial-types';
2
- export declare const useTutorial: () => {
3
- open: () => void;
4
- steps: TutorialStep[];
5
- };
@@ -1,10 +0,0 @@
1
- import { useEffect, useState } from 'react';
2
- import { MotiaTutorial } from '../engine/tutorial-engine';
3
- export const useTutorial = () => {
4
- const open = () => MotiaTutorial.open();
5
- const [steps, setSteps] = useState([]);
6
- useEffect(() => {
7
- MotiaTutorial.onStepsRegistered(() => setSteps(MotiaTutorial.steps));
8
- }, []);
9
- return { open, steps };
10
- };
@@ -1,2 +0,0 @@
1
- import type { FC } from 'react';
2
- export declare const TutorialButton: FC;
@@ -1,21 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button } from '@motiadev/ui';
3
- import { Book } from 'lucide-react';
4
- import { motiaAnalytics } from '@/lib/motia-analytics';
5
- import { Tooltip } from '../ui/tooltip';
6
- import { useTutorial } from './hooks/use-tutorial';
7
- export const TutorialButton = () => {
8
- const { open, steps } = useTutorial();
9
- const isTutorialFlowMissing = steps.length === 0;
10
- const onTutorialButtonClick = () => {
11
- if (!isTutorialFlowMissing) {
12
- open();
13
- }
14
- motiaAnalytics.track('tutorial_button_clicked', { isTutorialFlowMissing });
15
- };
16
- const trigger = (_jsxs(Button, { "data-testid": "tutorial-trigger", variant: "default", onClick: () => onTutorialButtonClick(), children: [_jsx(Book, { className: "h-4 w-4" }), "Tutorial"] }));
17
- if (isTutorialFlowMissing) {
18
- return (_jsx(Tooltip, { content: _jsxs("div", { className: "flex flex-col gap-4 p-4 max-w-[320px]", children: [_jsx("p", { className: "text-sm wrap-break-word p-0 m-0", children: "In order to start the tutorial, you need to download the tutorial steps using the Motia CLI. In your terminal execute the following command to create a new project:" }), _jsx("pre", { className: "text-sm font-bold", children: "npx motia@latest create" })] }), children: trigger }));
19
- }
20
- return trigger;
21
- };
@@ -1,14 +0,0 @@
1
- import type React from 'react';
2
- import type { TutorialImage } from './engine/tutorial-types';
3
- type TutorialStepProps = {
4
- step: number;
5
- totalSteps: number;
6
- title: string;
7
- description: React.ReactNode;
8
- link?: string;
9
- image?: TutorialImage;
10
- onNext: () => void;
11
- onClose: () => void;
12
- };
13
- export declare const TutorialStep: React.ForwardRefExoticComponent<TutorialStepProps & React.RefAttributes<HTMLDivElement>>;
14
- export {};
@@ -1,19 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { BackgroundEffect } from '@motiadev/ui';
3
- import { forwardRef, useEffect } from 'react';
4
- export const TutorialStep = forwardRef(({ step, totalSteps, title, description, link, image, onNext, onClose }, ref) => {
5
- useEffect(() => {
6
- const handleKeyDown = (e) => {
7
- if (step > 0 && e.key === 'Escape') {
8
- onClose();
9
- }
10
- else if (step > 0 && e.key === 'ArrowRight') {
11
- onNext();
12
- }
13
- };
14
- window.addEventListener('keydown', handleKeyDown);
15
- return () => window.removeEventListener('keydown', handleKeyDown);
16
- }, [onClose, onNext, step]);
17
- return (_jsxs("div", { ref: ref, className: "driver-popover ", children: [image && (_jsx("img", { src: image.src, alt: "Step visual", className: "driver-popover-image object-cover", style: { height: image.height, width: '100%' } })), _jsxs("div", { className: "isolate relative", children: [_jsx(BackgroundEffect, {}), _jsx("div", { className: "driver-popover-title", children: _jsx("h2", { className: "popover-title", children: title }) }), _jsx("div", { className: "driver-popover-description", children: description }), link && (_jsx("a", { href: link, target: "_blank", className: "text-foreground text-xs font-semibold px-4 hover:underline", children: "Learn more" })), _jsxs("div", { className: "driver-popover-footer flex items-center justify-between", children: [_jsxs("div", { className: "text-sm text-muted-foreground font-semibold", children: [step, " ", _jsx("span", { className: "text-foreground", children: "/" }), " ", totalSteps] }), _jsx("div", { className: "driver-popover-navigation-btns driver-popover-navigation-btns-hint flex gap-2", children: _jsx("button", { className: "driver-popover-next-btn", onClick: onNext, children: step < totalSteps ? 'Continue' : 'Finish' }) })] }), step < totalSteps && (_jsx("div", { className: "tutorial-opt-out-container", children: _jsx("button", { className: "tutorial-opt-out-button", onClick: onClose, children: "Close" }) }))] })] }));
18
- });
19
- TutorialStep.displayName = 'TutorialStep';
@@ -1,2 +0,0 @@
1
- import './tutorial.css';
2
- export declare const Tutorial: () => import("react/jsx-runtime").JSX.Element;
@@ -1,32 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { motiaAnalytics } from '@/lib/motia-analytics';
3
- import { useTutorialEngine } from './hooks/use-tutorial-engine';
4
- import { TutorialStep } from './tutorial-step';
5
- import './tutorial.css';
6
- export const Tutorial = () => {
7
- const engine = useTutorialEngine();
8
- const onNext = () => {
9
- const currentStep = engine.currentStepRef.current;
10
- const nextStep = currentStep + 1;
11
- engine.moveStep(nextStep);
12
- if (engine.currentStep === engine.totalSteps) {
13
- motiaAnalytics.track('tutorial_completed', {
14
- manualOpen: engine.manualOpenRef.current,
15
- });
16
- }
17
- else {
18
- motiaAnalytics.track('tutorial_next_step', {
19
- step: nextStep,
20
- manualOpen: engine.manualOpenRef.current,
21
- });
22
- }
23
- };
24
- const onClose = () => {
25
- motiaAnalytics.track('tutorial_closed', {
26
- step: engine.currentStepRef.current,
27
- manualOpen: engine.manualOpenRef.current,
28
- });
29
- engine.onClose();
30
- };
31
- return (_jsxs("div", { children: [_jsx("div", { className: "fixed inset-0 z-[9999]" }), _jsx("div", { className: "absolute top-5 left-5 w-full h-full rounded-lg shadow-[0_0_0_9999px_rgba(0,0,0,0.5)] z-[10000] pointer-events-none", ref: engine.highlighterRef }), _jsx(TutorialStep, { ref: engine.ref, step: engine.currentStep, totalSteps: engine.totalSteps, title: engine.title, description: engine.description, link: engine.link, image: engine.image, onNext: onNext, onClose: onClose })] }));
32
- };