@motiadev/workbench 0.3.1-beta.86 → 0.3.1-beta.88-406962

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 (220) hide show
  1. package/dist/index.d.ts +3 -4
  2. package/dist/index.html +3 -2
  3. package/dist/index.js +2 -3
  4. package/dist/public/icon.png +0 -0
  5. package/dist/public/motia-dark.png +0 -0
  6. package/dist/public/motia-light.png +0 -0
  7. package/dist/src/App.d.ts +2 -0
  8. package/dist/src/App.js +19 -0
  9. package/dist/src/components/endpoints/endpoint-badge.d.ts +1 -1
  10. package/dist/src/components/endpoints/endpoint-badge.js +8 -8
  11. package/dist/src/components/endpoints/endpoint-call.d.ts +3 -3
  12. package/dist/src/components/endpoints/endpoint-call.js +28 -23
  13. package/dist/src/components/endpoints/endpoint-response-schema.d.ts +10 -0
  14. package/dist/src/components/endpoints/endpoint-response-schema.js +17 -0
  15. package/dist/src/components/endpoints/endpoint-response.d.ts +8 -0
  16. package/dist/src/components/endpoints/endpoint-response.js +39 -0
  17. package/dist/src/components/endpoints/endpoints-page.js +14 -0
  18. package/dist/src/components/endpoints/hooks/use-get-endpoints.d.ts +1 -15
  19. package/dist/src/components/endpoints/json-editor.d.ts +9 -0
  20. package/dist/src/components/endpoints/json-editor.js +31 -0
  21. package/dist/src/components/flow/flow-page.d.ts +1 -0
  22. package/dist/src/components/flow/flow-page.js +20 -0
  23. package/dist/src/components/flow/flow-tab-menu-item.d.ts +1 -0
  24. package/dist/src/components/flow/flow-tab-menu-item.js +15 -0
  25. package/dist/src/{views → components}/flow/flow-view.d.ts +1 -2
  26. package/dist/src/components/flow/flow-view.js +21 -0
  27. package/dist/src/components/flow/hooks/use-get-flow-state.d.ts +10 -0
  28. package/dist/src/{views → components}/flow/hooks/use-get-flow-state.js +17 -10
  29. package/dist/src/{views → components}/flow/hooks/use-organize-nodes.d.ts +1 -1
  30. package/dist/src/{views → components}/flow/hooks/use-save-workflow-config.d.ts +1 -1
  31. package/dist/src/components/flow/nodes/api-flow-node.d.ts +2 -0
  32. package/dist/src/{views → components}/flow/nodes/api-flow-node.js +1 -1
  33. package/dist/src/components/flow/nodes/cron-flow-node.d.ts +2 -0
  34. package/dist/src/components/flow/nodes/cron-flow-node.js +5 -0
  35. package/dist/src/{views → components}/flow/nodes/event-flow-node.d.ts +1 -1
  36. package/dist/src/components/flow/nodes/event-flow-node.js +5 -0
  37. package/dist/src/components/flow/nodes/noop-flow-node.d.ts +2 -0
  38. package/dist/src/{views → components}/flow/nodes/noop-flow-node.js +1 -1
  39. package/dist/src/components/header/header.js +3 -11
  40. package/dist/src/components/logs/log-detail.d.ts +3 -1
  41. package/dist/src/components/logs/log-detail.js +33 -11
  42. package/dist/src/components/logs/log-level-badge.js +6 -6
  43. package/dist/src/components/logs/log-level-dot.js +7 -7
  44. package/dist/src/components/logs/logs-page.js +26 -0
  45. package/dist/src/components/observability/events/code/function-call.js +1 -1
  46. package/dist/src/components/observability/events/trace-event.d.ts +1 -1
  47. package/dist/src/components/observability/events/trace-log-event.d.ts +1 -1
  48. package/dist/src/components/observability/events/trace-log-event.js +2 -2
  49. package/dist/src/components/observability/hooks/use-get-endtime.d.ts +1 -1
  50. package/dist/src/components/observability/trace-item/trace-item-detail.d.ts +1 -0
  51. package/dist/src/components/observability/trace-item/trace-item-detail.js +5 -4
  52. package/dist/src/components/observability/trace-item/trace-item.d.ts +1 -0
  53. package/dist/src/components/observability/trace-item/trace-item.js +11 -17
  54. package/dist/src/components/observability/trace-status.d.ts +6 -10
  55. package/dist/src/components/observability/trace-status.js +7 -32
  56. package/dist/src/components/observability/trace-timeline.js +16 -4
  57. package/dist/src/components/observability/traces-groups.d.ts +2 -2
  58. package/dist/src/components/observability/traces-groups.js +4 -4
  59. package/dist/src/components/observability/traces-page.js +12 -0
  60. package/dist/src/components/sidebar/sidebar.d.ts +8 -0
  61. package/dist/src/components/sidebar/sidebar.js +39 -0
  62. package/dist/src/components/states/hooks/states-hooks.d.ts +7 -3
  63. package/dist/src/components/states/hooks/states-hooks.js +5 -33
  64. package/dist/src/components/states/state-detail.d.ts +2 -1
  65. package/dist/src/components/states/state-detail.js +15 -9
  66. package/dist/src/components/states/state-value.js +7 -7
  67. package/dist/src/components/states/states-page.js +18 -0
  68. package/dist/src/components/ui/badge.d.ts +1 -1
  69. package/dist/src/components/ui/table.js +1 -1
  70. package/dist/src/components/ui/theme-toggle.js +4 -3
  71. package/dist/src/hooks/use-fetch-flows.d.ts +1 -5
  72. package/dist/src/hooks/use-fetch-flows.js +18 -13
  73. package/dist/src/hooks/use-log-listener.js +2 -2
  74. package/dist/src/hooks/use-update-handle-positions.d.ts +10 -0
  75. package/dist/src/hooks/use-update-handle-positions.js +35 -0
  76. package/dist/src/index.css +36 -176
  77. package/dist/src/lib/utils.d.ts +1 -0
  78. package/dist/src/lib/utils.js +4 -0
  79. package/dist/src/main.d.ts +1 -0
  80. package/dist/src/main.js +4 -11
  81. package/dist/src/publicComponents/api-node.js +2 -4
  82. package/dist/src/publicComponents/{base-handle.d.ts → base-node/base-handle.d.ts} +1 -0
  83. package/dist/src/publicComponents/base-node/base-handle.js +8 -0
  84. package/dist/src/publicComponents/base-node/base-node.d.ts +21 -0
  85. package/dist/src/publicComponents/base-node/base-node.js +13 -0
  86. package/dist/src/publicComponents/{emits.d.ts → base-node/emits.d.ts} +1 -1
  87. package/dist/src/publicComponents/base-node/emits.js +5 -0
  88. package/dist/src/{views/flow/nodes → publicComponents/base-node}/language-indicator.d.ts +1 -1
  89. package/dist/src/{views/flow/nodes → publicComponents/base-node}/language-indicator.js +8 -7
  90. package/dist/src/publicComponents/base-node/node-header.d.ts +12 -0
  91. package/dist/src/publicComponents/base-node/node-header.js +30 -0
  92. package/dist/src/publicComponents/base-node/node-sidebar.d.ts +18 -0
  93. package/dist/src/publicComponents/base-node/node-sidebar.js +20 -0
  94. package/dist/src/publicComponents/base-node/subscribe.js +4 -0
  95. package/dist/src/publicComponents/cron-node.d.ts +2 -1
  96. package/dist/src/publicComponents/cron-node.js +3 -4
  97. package/dist/src/publicComponents/event-node.d.ts +1 -5
  98. package/dist/src/publicComponents/event-node.js +4 -6
  99. package/dist/src/publicComponents/node-details.js +21 -12
  100. package/dist/src/publicComponents/node-props.d.ts +13 -6
  101. package/dist/src/publicComponents/noop-node.d.ts +3 -7
  102. package/dist/src/publicComponents/noop-node.js +3 -3
  103. package/dist/src/stores/use-flow-store.d.ts +18 -0
  104. package/dist/src/stores/use-flow-store.js +15 -0
  105. package/dist/src/stores/use-global-store.d.ts +24 -0
  106. package/dist/src/stores/use-global-store.js +20 -0
  107. package/dist/src/stores/{use-logs.d.ts → use-logs-store.d.ts} +1 -3
  108. package/dist/src/stores/use-logs-store.js +10 -0
  109. package/dist/src/stores/use-tabs-store.d.ts +17 -0
  110. package/dist/src/stores/use-tabs-store.js +13 -0
  111. package/dist/src/stores/use-theme-store.d.ts +17 -0
  112. package/dist/src/stores/use-theme-store.js +26 -0
  113. package/dist/src/types/endpoint.d.ts +14 -0
  114. package/dist/src/{views/flow/nodes/nodes.types.d.ts → types/flow.d.ts} +45 -0
  115. package/dist/src/types/flow.js +1 -0
  116. package/dist/tsconfig.app.tsbuildinfo +1 -1
  117. package/dist/tsconfig.node.tsbuildinfo +1 -1
  118. package/package.json +28 -26
  119. package/dist/public/.empty +0 -0
  120. package/dist/src/components/app-sidebar.d.ts +0 -1
  121. package/dist/src/components/app-sidebar.js +0 -12
  122. package/dist/src/components/endpoints/endpoints.d.ts +0 -1
  123. package/dist/src/components/endpoints/endpoints.js +0 -34
  124. package/dist/src/components/endpoints/selected-endpoint.d.ts +0 -7
  125. package/dist/src/components/endpoints/selected-endpoint.js +0 -7
  126. package/dist/src/components/logs/log-console.d.ts +0 -1
  127. package/dist/src/components/logs/log-console.js +0 -69
  128. package/dist/src/components/logs/log-field.d.ts +0 -7
  129. package/dist/src/components/logs/log-field.js +0 -20
  130. package/dist/src/components/logs/logs.d.ts +0 -1
  131. package/dist/src/components/logs/logs.js +0 -18
  132. package/dist/src/components/observability/observability-stats.d.ts +0 -5
  133. package/dist/src/components/observability/observability-stats.js +0 -17
  134. package/dist/src/components/states/states.d.ts +0 -1
  135. package/dist/src/components/states/states.js +0 -21
  136. package/dist/src/components/ui/BadgeCount.d.ts +0 -7
  137. package/dist/src/components/ui/BadgeCount.js +0 -13
  138. package/dist/src/components/ui/button.d.ts +0 -11
  139. package/dist/src/components/ui/button.js +0 -33
  140. package/dist/src/components/ui/card.d.ts +0 -8
  141. package/dist/src/components/ui/card.js +0 -16
  142. package/dist/src/components/ui/collapsible.d.ts +0 -5
  143. package/dist/src/components/ui/collapsible.js +0 -5
  144. package/dist/src/components/ui/dialog.d.ts +0 -19
  145. package/dist/src/components/ui/dialog.js +0 -22
  146. package/dist/src/components/ui/dropdown-menu.d.ts +0 -25
  147. package/dist/src/components/ui/dropdown-menu.js +0 -50
  148. package/dist/src/components/ui/input.d.ts +0 -3
  149. package/dist/src/components/ui/input.js +0 -8
  150. package/dist/src/components/ui/logo-icon.d.ts +0 -5
  151. package/dist/src/components/ui/logo-icon.js +0 -5
  152. package/dist/src/components/ui/navigation-menu.d.ts +0 -13
  153. package/dist/src/components/ui/navigation-menu.js +0 -30
  154. package/dist/src/components/ui/scroll-area.d.ts +0 -5
  155. package/dist/src/components/ui/scroll-area.js +0 -9
  156. package/dist/src/components/ui/select.d.ts +0 -13
  157. package/dist/src/components/ui/select.js +0 -25
  158. package/dist/src/components/ui/separator.d.ts +0 -4
  159. package/dist/src/components/ui/separator.js +0 -8
  160. package/dist/src/components/ui/sheet.d.ts +0 -25
  161. package/dist/src/components/ui/sheet.js +0 -36
  162. package/dist/src/components/ui/sidebar.d.ts +0 -12
  163. package/dist/src/components/ui/sidebar.js +0 -25
  164. package/dist/src/components/ui/skeleton.d.ts +0 -3
  165. package/dist/src/components/ui/skeleton.js +0 -6
  166. package/dist/src/components/ui/switch.d.ts +0 -4
  167. package/dist/src/components/ui/switch.js +0 -7
  168. package/dist/src/components/ui/tabs.d.ts +0 -7
  169. package/dist/src/components/ui/tabs.js +0 -12
  170. package/dist/src/components/ui/textarea.d.ts +0 -3
  171. package/dist/src/components/ui/textarea.js +0 -8
  172. package/dist/src/components/ui/tooltip.d.ts +0 -7
  173. package/dist/src/components/ui/tooltip.js +0 -11
  174. package/dist/src/hooks/use-list-flows.d.ts +0 -9
  175. package/dist/src/hooks/use-list-flows.js +0 -8
  176. package/dist/src/hooks/use-theme.d.ts +0 -6
  177. package/dist/src/hooks/use-theme.js +0 -28
  178. package/dist/src/publicComponents/base-handle.js +0 -10
  179. package/dist/src/publicComponents/base-node.d.ts +0 -16
  180. package/dist/src/publicComponents/base-node.js +0 -25
  181. package/dist/src/publicComponents/colorMap.d.ts +0 -6
  182. package/dist/src/publicComponents/colorMap.js +0 -6
  183. package/dist/src/publicComponents/components/header-bar.d.ts +0 -11
  184. package/dist/src/publicComponents/components/header-bar.js +0 -15
  185. package/dist/src/publicComponents/emits.js +0 -6
  186. package/dist/src/publicComponents/subscribe.js +0 -5
  187. package/dist/src/route-wrapper.d.ts +0 -2
  188. package/dist/src/route-wrapper.js +0 -5
  189. package/dist/src/routes/endpoints-page.js +0 -5
  190. package/dist/src/routes/flow.d.ts +0 -1
  191. package/dist/src/routes/flow.js +0 -11
  192. package/dist/src/routes/index.d.ts +0 -1
  193. package/dist/src/routes/index.js +0 -5
  194. package/dist/src/routes/logs-page.js +0 -12
  195. package/dist/src/routes/states-page.js +0 -5
  196. package/dist/src/routes/traces-page.js +0 -14
  197. package/dist/src/stores/use-logs.js +0 -52
  198. package/dist/src/views/flow/arrow-head.d.ts +0 -8
  199. package/dist/src/views/flow/arrow-head.js +0 -6
  200. package/dist/src/views/flow/flow-view.js +0 -48
  201. package/dist/src/views/flow/hooks/use-get-flow-state.d.ts +0 -52
  202. package/dist/src/views/flow/legend.d.ts +0 -4
  203. package/dist/src/views/flow/legend.js +0 -51
  204. package/dist/src/views/flow/nodes/api-flow-node.d.ts +0 -4
  205. package/dist/src/views/flow/nodes/event-flow-node.js +0 -5
  206. package/dist/src/views/flow/nodes/noop-flow-node.d.ts +0 -4
  207. /package/dist/src/{routes → components/endpoints}/endpoints-page.d.ts +0 -0
  208. /package/dist/src/{views → components}/flow/base-edge.d.ts +0 -0
  209. /package/dist/src/{views → components}/flow/base-edge.js +0 -0
  210. /package/dist/src/{views → components}/flow/flow-loader.d.ts +0 -0
  211. /package/dist/src/{views → components}/flow/flow-loader.js +0 -0
  212. /package/dist/src/{views → components}/flow/hooks/use-organize-nodes.js +0 -0
  213. /package/dist/src/{views → components}/flow/hooks/use-save-workflow-config.js +0 -0
  214. /package/dist/src/{views → components}/flow/node-organizer.d.ts +0 -0
  215. /package/dist/src/{views → components}/flow/node-organizer.js +0 -0
  216. /package/dist/src/{routes → components/logs}/logs-page.d.ts +0 -0
  217. /package/dist/src/{routes → components/observability}/traces-page.d.ts +0 -0
  218. /package/dist/src/{routes → components/states}/states-page.d.ts +0 -0
  219. /package/dist/src/publicComponents/{subscribe.d.ts → base-node/subscribe.d.ts} +0 -0
  220. /package/dist/src/{views/flow/nodes/nodes.types.js → types/endpoint.js} +0 -0
@@ -1,15 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '@/lib/utils';
2
3
  import { cva } from 'class-variance-authority';
3
4
  import { SquareMinus, SquarePlus } from 'lucide-react';
4
5
  import React, { useState } from 'react';
5
- import { cn } from '../../lib/utils';
6
- const valueVariants = cva('text-muted-foreground text-sm py-2', {
6
+ const valueVariants = cva('text-muted-foreground text-sm', {
7
7
  variants: {
8
8
  variant: {
9
- boolean: 'text-sky-400',
10
- number: 'text-teal-400',
9
+ boolean: 'text-sky-400 font-mono font-bold',
10
+ number: 'text-teal-400 font-mono font-bold',
11
11
  undefined: 'text-muted-foreground',
12
- string: 'text-muted-foreground',
12
+ string: 'text-muted-foreground font-mono font-medium',
13
13
  object: 'text-gray-800',
14
14
  },
15
15
  },
@@ -19,7 +19,7 @@ const valueVariants = cva('text-muted-foreground text-sm py-2', {
19
19
  });
20
20
  const Value = ({ value, variant, label, }) => {
21
21
  const displayValue = typeof value === 'string' ? value : JSON.stringify(value);
22
- return (_jsxs("div", { className: "flex flex-col gap-1", children: [label && _jsx("div", { className: "text-md font-semibold py-2", children: label }), _jsx("div", { className: valueVariants({ variant }), children: displayValue })] }));
22
+ return (_jsxs("div", { className: "flex flex-col gap-1", children: [label && _jsx("div", { className: "text-md font-bold", children: label }), _jsx("div", { className: valueVariants({ variant }), children: displayValue })] }));
23
23
  };
24
24
  export const StateValue = ({ value, label, isRoot = false }) => {
25
25
  const [isOpen, setIsOpen] = useState(true);
@@ -43,7 +43,7 @@ export const StateValue = ({ value, label, isRoot = false }) => {
43
43
  const [openBracket, closeBracket] = isRoot ? [] : isArray ? ['[', ']'] : ['{', '}'];
44
44
  if (typeof value === 'object' && !!value) {
45
45
  const valueObject = value;
46
- return (_jsxs("div", { className: "flex flex-col gap-2", children: [(label || openBracket) && (_jsxs("div", { className: "flex gap-1 items-center text-md font-semibold hover:bg-gray-800 rounded-md py-2", onClick: toggle, children: [isOpen ? (_jsx(SquareMinus, { className: "w-4 h-4 text-muted-foreground" })) : (_jsx(SquarePlus, { className: "w-4 h-4 text-muted-foreground" })), label, ' ', !isRoot && (_jsxs("span", { className: "text-muted-foreground text-sm", children: [openBracket, !isOpen && ` ... ${closeBracket}`] }))] })), isOpen &&
46
+ return (_jsxs("div", { className: "flex flex-col gap-2", children: [(label || openBracket) && (_jsxs("div", { className: "flex gap-1 items-center text-md font-bold hover:bg-muted-foreground/10 rounded-md py-2 cursor-pointer", onClick: toggle, children: [isOpen ? (_jsx(SquareMinus, { className: "w-4 h-4 text-muted-foreground" })) : (_jsx(SquarePlus, { className: "w-4 h-4 text-muted-foreground" })), label, ' ', !isRoot && (_jsxs("span", { className: "text-muted-foreground text-sm", children: [openBracket, !isOpen && ` ... ${closeBracket}`] }))] })), isOpen &&
47
47
  !!valueObject &&
48
48
  Object.keys(valueObject).map((key) => (_jsx("div", { className: cn('flex flex-col gap-2', !isRoot && 'ml-4'), children: _jsx("span", { className: "text-md", children: _jsx(StateValue, { label: isArray ? undefined : key, value: valueObject[key] }) }) }, key))), !isRoot && isOpen && _jsx("span", { className: "text-muted-foreground text-sm", children: closeBracket })] }));
49
49
  }
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useGlobalStore } from '@/stores/use-global-store';
3
+ import { cn } from '@motiadev/ui';
4
+ import { useMemo } from 'react';
5
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
6
+ import { useGetStateItems } from './hooks/states-hooks';
7
+ import { StateDetail } from './state-detail';
8
+ export const StatesPage = () => {
9
+ const selectedStateId = useGlobalStore((state) => state.selectedStateId);
10
+ const selectStateId = useGlobalStore((state) => state.selectStateId);
11
+ const items = useGetStateItems();
12
+ const selectedItem = useMemo(() => (selectedStateId ? items.find((item) => `${item.groupId}:${item.key}` === selectedStateId) : null), [items, selectedStateId]);
13
+ const handleRowClick = (item) => selectStateId(`${item.groupId}:${item.key}`);
14
+ const onClose = () => selectStateId(undefined);
15
+ return (_jsxs("div", { className: "flex flex-row gap-4 h-full", children: [selectedItem && _jsx(StateDetail, { state: selectedItem, onClose: onClose }), _jsxs(Table, { children: [_jsx(TableHeader, { className: "sticky top-0 bg-background", children: _jsxs(TableRow, { children: [_jsx(TableHead, { className: "rounded-0", children: "Group ID" }), _jsx(TableHead, { children: "Key" }), _jsx(TableHead, { children: "Type" })] }) }), _jsx(TableBody, { children: items.map((item) => (_jsxs(TableRow, { "data-testid": `item-${item}`, onClick: () => handleRowClick(item), className: cn('font-mono font-semibold', selectedItem === item
16
+ ? 'bg-muted-foreground/10 hover:bg-muted-foreground/20'
17
+ : 'hover:bg-muted-foreground/10'), children: [_jsx(TableCell, { className: "hover:bg-transparent", children: item.groupId }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.key }), _jsx(TableCell, { className: "hover:bg-transparent", children: item.type })] }, `${item.groupId}:${item.key}`))) })] })] }));
18
+ };
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { type VariantProps } from 'class-variance-authority';
3
3
  declare const badgeVariants: (props?: ({
4
- variant?: "default" | "destructive" | "outline" | "secondary" | "info" | "error" | "warning" | "red-rounded" | "red-dot" | null | undefined;
4
+ variant?: "error" | "default" | "secondary" | "destructive" | "outline" | "info" | "warning" | "red-rounded" | "red-dot" | null | undefined;
5
5
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
6
6
  export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
7
7
  }
@@ -11,7 +11,7 @@ const TableFooter = React.forwardRef(({ className, ...props }, ref) => (_jsx("tf
11
11
  TableFooter.displayName = 'TableFooter';
12
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
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 first:rounded-l-lg last:rounded-r-lg [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]', className), ...props })));
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
15
  TableHead.displayName = 'TableHead';
16
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
17
  TableCell.displayName = 'TableCell';
@@ -1,11 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Moon, Sun } from 'lucide-react';
3
- import { useTheme } from '@/hooks/use-theme';
3
+ import { useThemeStore } from '@/stores/use-theme-store';
4
4
  import { cn } from '@/lib/utils';
5
5
  export const ThemeToggle = () => {
6
- const { theme, setTheme } = useTheme();
6
+ const theme = useThemeStore((state) => state.theme);
7
+ const setTheme = useThemeStore((state) => state.setTheme);
7
8
  const toggleTheme = () => {
8
9
  setTheme(theme === 'light' ? 'dark' : 'light');
9
10
  };
10
- return (_jsxs("button", { onClick: toggleTheme, className: "relative flex items-center cursor-pointer w-16 h-8 bg-muted 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') }) })] }));
11
+ 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') }) })] }));
11
12
  };
@@ -1,5 +1 @@
1
- import { FlowConfigResponse, FlowResponse } from '@/views/flow/hooks/use-get-flow-state';
2
- export declare const useFetchFlows: (flowId: string) => {
3
- flow: FlowResponse | null;
4
- flowConfig: FlowConfigResponse | null;
5
- };
1
+ export declare const useFetchFlows: () => void;
@@ -1,17 +1,22 @@
1
- import { useStreamItem } from '@motiadev/stream-client-react';
2
- export const useFetchFlows = (flowId) => {
3
- const { data: flow } = useStreamItem({
1
+ import { useFlowStore } from '@/stores/use-flow-store';
2
+ import { useStreamGroup } from '@motiadev/stream-client-react';
3
+ import { useEffect } from 'react';
4
+ export const useFetchFlows = () => {
5
+ const setFlows = useFlowStore((state) => state.setFlows);
6
+ const selectFlowId = useFlowStore((state) => state.selectFlowId);
7
+ const selectedFlowId = useFlowStore((state) => state.selectedFlowId);
8
+ const { data: flows } = useStreamGroup({
4
9
  streamName: '__motia.flows',
5
10
  groupId: 'default',
6
- id: flowId,
7
11
  });
8
- const { data: flowConfig } = useStreamItem({
9
- streamName: '__motia.flowsConfig',
10
- groupId: 'default',
11
- id: flowId,
12
- });
13
- return {
14
- flow,
15
- flowConfig,
16
- };
12
+ useEffect(() => {
13
+ if (flows)
14
+ setFlows(flows.map((flow) => flow.id));
15
+ }, [flows, setFlows]);
16
+ useEffect(() => {
17
+ if ((!selectedFlowId && flows.length > 0) ||
18
+ (selectedFlowId && flows.length > 0 && !flows.find((flow) => flow.id === selectedFlowId))) {
19
+ selectFlowId(flows[0].id);
20
+ }
21
+ }, [flows, selectedFlowId, selectFlowId, selectedFlowId]);
17
22
  };
@@ -1,7 +1,7 @@
1
- import { useLogs } from '@/stores/use-logs';
1
+ import { useLogsStore } from '@/stores/use-logs-store';
2
2
  import { useStreamEventHandler, useStreamGroup } from '@motiadev/stream-client-react';
3
3
  export const useLogListener = () => {
4
- const addLog = useLogs((state) => state.addLog);
4
+ const addLog = useLogsStore((state) => state.addLog);
5
5
  const { event } = useStreamGroup({ streamName: '__motia.logs', groupId: 'default' });
6
6
  useStreamEventHandler({ event, type: 'log', listener: addLog }, [addLog]);
7
7
  };
@@ -0,0 +1,10 @@
1
+ import { Position } from '@xyflow/react';
2
+ import { 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
+ };
@@ -0,0 +1,35 @@
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 === 'right' ? Position.Right : Position.Bottom;
6
+ const targetPosition = data.nodeConfig?.targetHandlePosition === 'left' ? Position.Left : Position.Top;
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,194 +1,54 @@
1
- @import 'tailwindcss';
1
+ @import "@motiadev/ui/styles.css";
2
+ @import "@motiadev/ui/globals.css";
2
3
  @import 'tw-animate-css';
3
4
  @config "../tailwind.config.js";
4
5
 
5
- @custom-variant dark (&:is(.dark *));
6
-
7
- :root {
8
- line-height: 1.5;
9
- font-size: 16px;
10
-
11
- color-scheme: light dark;
12
- font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"), serif;
13
- font-synthesis: none;
14
- text-rendering: optimizeLegibility;
15
- -webkit-font-smoothing: antialiased;
16
- -moz-osx-font-smoothing: grayscale;
17
- width: 100%;
18
- font-optical-sizing: auto;
19
-
20
- --radius: 0.625rem;
21
- --background: oklch(1 0 0);
22
- --foreground: oklch(0.145 0 0);
23
- --card: oklch(0.98 0 0);
24
- --card-foreground: oklch(0.145 0 0);
25
- --popover: oklch(1 0 0);
26
- --popover-foreground: oklch(0.145 0 0);
27
- --primary: oklch(0.205 0 0);
28
- --primary-foreground: oklch(0.985 0 0);
29
- --secondary: oklch(0.97 0 0);
30
- --secondary-foreground: oklch(0.205 0 0);
31
- --muted: oklch(0.97 0 0);
32
- --muted-foreground: oklch(0.556 0 0);
33
- --accent: oklch(0.97 0 0);
34
- --accent-foreground: oklch(0.205 0 0);
35
- --destructive: oklch(0.577 0.245 27.325);
36
- --border: oklch(0.922 0 0);
37
- --input: oklch(0.922 0 0);
38
- --ring: oklch(0.708 0 0);
39
- --chart-1: oklch(0.646 0.222 41.116);
40
- --chart-2: oklch(0.6 0.118 184.704);
41
- --chart-3: oklch(0.398 0.07 227.392);
42
- --chart-4: oklch(0.828 0.189 84.429);
43
- --chart-5: oklch(0.769 0.188 70.08);
44
- --header: oklch(0.985 0 0);
45
- --header-foreground: oklch(0.145 0 0);
46
- --header-primary: oklch(0.205 0 0);
47
- --header-primary-foreground: oklch(0.985 0 0);
48
- --header-accent: oklch(0.97 0 0);
49
- --header-accent-foreground: oklch(0.205 0 0);
50
- --header-border: oklch(0.922 0 0);
51
- --header-ring: oklch(0.708 0 0);
52
- --sidebar: oklch(0.985 0 0);
53
- --sidebar-foreground: oklch(0.145 0 0);
54
- --sidebar-primary: oklch(0.205 0 0);
55
- --sidebar-primary-foreground: oklch(0.985 0 0);
56
- --sidebar-accent: oklch(0.97 0 0);
57
- --sidebar-accent-foreground: oklch(0.205 0 0);
58
- --sidebar-border: oklch(0.922 0 0);
59
- --sidebar-ring: oklch(0.708 0 0);
60
- }
61
-
62
- .dark {
63
- --background: oklch(0.145 0 0);
64
- --foreground: oklch(0.985 0 0);
65
- --card: oklch(0.205 0 0);
66
- --card-foreground: oklch(0.985 0 0);
67
- --popover: oklch(0.205 0 0);
68
- --popover-foreground: oklch(0.985 0 0);
69
- --primary: oklch(0.922 0 0);
70
- --primary-foreground: oklch(0.205 0 0);
71
- --secondary: oklch(0.269 0 0);
72
- --secondary-foreground: oklch(0.985 0 0);
73
- --muted: oklch(0.269 0 0);
74
- --muted-foreground: oklch(0.708 0 0);
75
- --accent: oklch(0.269 0 0);
76
- --accent-foreground: oklch(0.985 0 0);
77
- --destructive: oklch(0.704 0.191 22.216);
78
- --border: oklch(1 0 0 / 10%);
79
- --input: oklch(1 0 0 / 15%);
80
- --ring: oklch(0.556 0 0);
81
- --chart-1: oklch(0.488 0.243 264.376);
82
- --chart-2: oklch(0.696 0.17 162.48);
83
- --chart-3: oklch(0.769 0.188 70.08);
84
- --chart-4: oklch(0.627 0.265 303.9);
85
- --chart-5: oklch(0.645 0.246 16.439);
86
- --header: oklch(0.205 0 0);
87
- --header-foreground: oklch(0.985 0 0);
88
- --header-primary: oklch(0.488 0.243 264.376);
89
- --header-primary-foreground: oklch(0.985 0 0);
90
- --header-accent: oklch(0.269 0 0);
91
- --header-accent-foreground: oklch(0.985 0 0);
92
- --header-border: oklch(1 0 0 / 10%);
93
- --header-ring: oklch(0.556 0 0);
94
- --sidebar: oklch(0.205 0 0);
95
- --sidebar-foreground: oklch(0.985 0 0);
96
- --sidebar-primary: oklch(0.488 0.243 264.376);
97
- --sidebar-primary-foreground: oklch(0.985 0 0);
98
- --sidebar-accent: oklch(0.269 0 0);
99
- --sidebar-accent-foreground: oklch(0.985 0 0);
100
- --sidebar-border: oklch(1 0 0 / 10%);
101
- --sidebar-ring: oklch(0.556 0 0);
102
- }
103
-
104
- @theme inline {
105
- --radius-sm: calc(var(--radius) - 4px);
106
- --radius-md: calc(var(--radius) - 2px);
107
- --radius-lg: var(--radius);
108
- --radius-xl: calc(var(--radius) + 4px);
109
- --color-background: var(--background);
110
- --color-foreground: var(--foreground);
111
- --color-card: var(--card);
112
- --color-card-foreground: var(--card-foreground);
113
- --color-popover: var(--popover);
114
- --color-popover-foreground: var(--popover-foreground);
115
- --color-primary: var(--primary);
116
- --color-primary-foreground: var(--primary-foreground);
117
- --color-secondary: var(--secondary);
118
- --color-secondary-foreground: var(--secondary-foreground);
119
- --color-muted: var(--muted);
120
- --color-muted-foreground: var(--muted-foreground);
121
- --color-accent: var(--accent);
122
- --color-accent-foreground: var(--accent-foreground);
123
- --color-destructive: var(--destructive);
124
- --color-border: var(--border);
125
- --color-input: var(--input);
126
- --color-ring: var(--ring);
127
- --color-chart-1: var(--chart-1);
128
- --color-chart-2: var(--chart-2);
129
- --color-chart-3: var(--chart-3);
130
- --color-chart-4: var(--chart-4);
131
- --color-chart-5: var(--chart-5);
132
- --color-header: var(--header);
133
- --color-header-foreground: var(--header-foreground);
134
- --color-header-primary: var(--header-primary);
135
- --color-header-primary-foreground: var(--header-primary-foreground);
136
- --color-header-accent: var(--header-accent);
137
- --color-header-accent-foreground: var(--header-accent-foreground);
138
- --color-header-border: var(--header-border);
139
- --color-header-ring: var(--header-ring);
140
- --color-sidebar: var(--sidebar);
141
- --color-sidebar-foreground: var(--sidebar-foreground);
142
- --color-sidebar-primary: var(--sidebar-primary);
143
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
144
- --color-sidebar-accent: var(--sidebar-accent);
145
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
146
- --color-sidebar-border: var(--sidebar-border);
147
- --color-sidebar-ring: var(--sidebar-ring);
148
- }
149
-
150
- body {
151
- margin: 0;
152
- place-items: center;
153
- min-height: 100dvh;
154
- width: 100%;
155
- font-family: 'DM Sans', sans-serif;
156
- }
157
-
158
- body,
159
- #root {
160
- width: 100dvw;
161
- height: 100dvh;
162
- }
163
-
164
- strong {
165
- font-weight: 800;
6
+ @keyframes flowDash {
7
+ 0% {
8
+ stroke-dashoffset: 0;
9
+ }
10
+ 100% {
11
+ stroke-dashoffset: -20;
12
+ }
166
13
  }
167
14
 
168
- .react-flow__attribution {
169
- display: none;
15
+ .json-view {
16
+ background:rgba(0, 0, 0, 0.1);
170
17
  }
171
18
 
172
- @layer base {
173
- * {
174
- @apply border-border;
19
+ .dark {
20
+ .react-flow__panel {
21
+ background: var(--background)
175
22
  }
176
- body {
177
- @apply bg-background text-foreground;
23
+ .json-view {
24
+ background: rgba(0, 0, 0, 0.8);
178
25
  }
179
26
  }
180
27
 
181
- @keyframes flowDash {
182
- 0% {
183
- stroke-dashoffset: 0;
184
- }
185
- 100% {
186
- stroke-dashoffset: -20;
187
- }
28
+ .font-mono {
29
+ font-family: 'IBM Plex Mono', 'Courier New', monospace;
30
+ font-size: 14px;
188
31
  }
189
32
 
190
33
  .edge-animated {
191
34
  stroke-dasharray: 5; /* length of dash pattern */
192
35
  stroke-linecap: round; /* round the dash ends */
193
36
  animation: flowDash 1s linear infinite;
37
+ }
38
+
39
+ .json-view {
40
+ border-radius: 8px;
41
+ padding: 12px 12px;
42
+ font-family: 'IBM Plex Mono', 'Courier New', monospace;
43
+ font-size: 14px;
44
+ line-height: 1.5;
45
+ font-weight: 500;
46
+ }
47
+
48
+ .json-view--pair, .json-view--property, .json-view > span {
49
+ line-height: 24px;
50
+ }
51
+
52
+ .json-view--property {
53
+ font-weight: 600;
194
54
  }
@@ -1,3 +1,4 @@
1
1
  import { type ClassValue } from 'clsx';
2
2
  export declare function cn(...inputs: ClassValue[]): string;
3
3
  export declare const formatDuration: (duration?: number) => string;
4
+ export declare const formatTimestamp: (time: number) => string;
@@ -10,3 +10,7 @@ export const formatDuration = (duration) => {
10
10
  return `${duration}ms`;
11
11
  return `${(duration / 1000).toFixed(1)}s`;
12
12
  };
13
+ export const formatTimestamp = (time) => {
14
+ const date = new Date(Number(time));
15
+ return `${date.toLocaleDateString('en-US', { year: undefined, month: 'short', day: '2-digit' })}, ${date.toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h24' })}.${date.getMilliseconds().toString().padStart(3, '0')}`;
16
+ };
@@ -1 +1,2 @@
1
+ import '@motiadev/ui/globals.css';
1
2
  import './index.css';
package/dist/src/main.js CHANGED
@@ -1,21 +1,14 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } 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, Route, Routes } from 'react-router';
6
5
  import { RootMotia } from './components/root-motia';
6
+ import '@motiadev/ui/globals.css';
7
7
  import './index.css';
8
- import { RouteWrapper } from './route-wrapper';
9
- import { Index } from './routes';
10
- import { EndpointsPage } from './routes/endpoints-page';
11
- import { Flow } from './routes/flow';
12
- import { LogsPage } from './routes/logs-page';
13
- import { StatesPage } from './routes/states-page';
14
- import { TracesPage } from './routes/traces-page';
15
- // Render the app
8
+ import { App } from './App';
16
9
  const rootElement = document.getElementById('root');
17
10
  if (!rootElement.innerHTML) {
18
11
  const root = createRoot(rootElement);
19
12
  const address = window.location.origin.replace('http', 'ws');
20
- root.render(_jsx(StrictMode, { children: _jsx(MotiaStreamProvider, { address: address, children: _jsx(BrowserRouter, { children: _jsx(RootMotia, { children: _jsx(RouteWrapper, { children: _jsxs(Routes, { children: [_jsx(Route, { path: "/", element: _jsx(Index, {}) }), _jsx(Route, { path: "/flow/:id", element: _jsx(Flow, {}) }), _jsx(Route, { path: "/logs", element: _jsx(LogsPage, {}) }), _jsx(Route, { path: "/states", element: _jsx(StatesPage, {}) }), _jsx(Route, { path: "/endpoints", element: _jsx(EndpointsPage, {}) }), _jsx(Route, { path: "/traces", element: _jsx(TracesPage, {}) })] }) }) }) }) }) }));
13
+ root.render(_jsx(StrictMode, { children: _jsx(MotiaStreamProvider, { address: address, children: _jsx(RootMotia, { children: _jsx(App, {}) }) }) }));
21
14
  }
@@ -1,7 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Webhook } from 'lucide-react';
3
- import { BaseNode } from './base-node';
4
- import { DetailItem, NodeDetails } from './node-details';
2
+ import { BaseNode } from './base-node/base-node';
5
3
  export const ApiNode = ({ data, children }) => {
6
- return (_jsxs(BaseNode, { variant: "api", title: data.name, language: data.language, disableSourceHandle: !data.emits?.length && !data.virtualEmits?.length, disableTargetHandle: !data.subscribes?.length && !data.virtualSubscribes?.length, children: [data.description && _jsx("div", { className: "text-sm text-muted-foreground", children: data.description }), children, data.webhookUrl && (_jsxs("div", { className: "flex gap-1 items-center text-xs text-muted-foreground", children: [_jsx(Webhook, { className: "w-3 h-3 text-muted-foreground/40" }), _jsx("div", { className: "font-mono", children: data.webhookUrl })] })), _jsx(NodeDetails, { type: "api", name: data.name, subscribes: data.subscribes, emits: data.emits, description: data.description, language: data.language, children: _jsx(DetailItem, { label: "Webhook URL", children: _jsxs("div", { className: "flex gap-1 items-center text-xs text-muted-foreground", children: [_jsx(Webhook, { className: "w-3 h-3 text-muted-foreground/40" }), _jsx("div", { className: "font-mono", children: data.webhookUrl })] }) }) })] }));
4
+ return (_jsxs(BaseNode, { data: data, variant: "api", title: data.name, language: data.language, subtitle: data.description, disableSourceHandle: !data.emits?.length && !data.virtualEmits?.length, disableTargetHandle: !data.subscribes?.length && !data.virtualSubscribes?.length, subscribes: data.subscribes, emits: data.emits, details: [{ label: 'Endpoint', value: data.webhookUrl }].filter((item) => !!item), children: [data.webhookUrl && (_jsx("div", { className: "flex gap-1 items-center text-xs text-muted-foreground", children: _jsx("div", { className: "font-mono", children: data.webhookUrl }) })), children] }));
7
5
  };
@@ -3,6 +3,7 @@ import { HandleProps } from '@xyflow/react';
3
3
  type Props = HandleProps & Omit<HTMLAttributes<HTMLDivElement>, 'id'> & {
4
4
  isHidden?: boolean;
5
5
  variant?: string | null;
6
+ onTogglePosition?: () => void;
6
7
  };
7
8
  export declare const BaseHandle: React.FC<Props>;
8
9
  export {};
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Position, Handle as RFHandle } from '@xyflow/react';
3
+ import clsx from 'clsx';
4
+ export const BaseHandle = (props) => {
5
+ const { isHidden, position, variant, onTogglePosition, ...rest } = props;
6
+ const isHorizontal = position === Position.Left || position === Position.Right;
7
+ return (_jsx("div", { className: clsx('absolute w-[6px] h-[6px]', position === Position.Top && '-top-[4px]', position === Position.Bottom && '-bottom-[4px]', position === Position.Left && '-left-[4px]', position === Position.Right && '-right-[4px]', isHorizontal ? 'top-1/2 -mt-[2px]' : 'left-1/2 -ml-[2px]', isHidden && 'hidden'), onClick: onTogglePosition, children: _jsx(RFHandle, { ...rest, position: position, style: { background: 'rgb(30,118,231)' }, className: "\n bg-white/50\n !static\n !w-[6px]\n !h-[6px]\n !min-w-[6px]\n !min-h-[6px]\n !p-0\n !border-none\n !transform-none\n !rounded-full\n !outline-none\n !shadow-none\n " }) }));
8
+ };
@@ -0,0 +1,21 @@
1
+ import { PanelDetailItem } from '@motiadev/ui';
2
+ import React, { PropsWithChildren } from 'react';
3
+ import { BaseNodeProps } from '../node-props';
4
+ type Props = PropsWithChildren<{
5
+ title: string;
6
+ subtitle?: string;
7
+ variant: 'event' | 'api' | 'noop' | 'cron';
8
+ language?: string;
9
+ className?: string;
10
+ disableSourceHandle?: boolean;
11
+ disableTargetHandle?: boolean;
12
+ details?: PanelDetailItem[];
13
+ emits?: Array<string | {
14
+ topic: string;
15
+ label?: string;
16
+ }>;
17
+ subscribes?: string[];
18
+ data: BaseNodeProps;
19
+ }>;
20
+ export declare const BaseNode: React.FC<Props>;
21
+ export {};
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useHandlePositions } from '@/hooks/use-update-handle-positions';
3
+ import { ChevronUp } from 'lucide-react';
4
+ import { useState } from 'react';
5
+ import { BaseHandle } from './base-handle';
6
+ import { LanguageIndicator } from './language-indicator';
7
+ import { NodeHeader } from './node-header';
8
+ import { NodeSidebar } from './node-sidebar';
9
+ export const BaseNode = ({ title, variant, children, disableSourceHandle, disableTargetHandle, language, subtitle, details, subscribes, emits, data, }) => {
10
+ const [isOpen, setIsOpen] = useState(false);
11
+ const { sourcePosition, targetPosition, toggleTargetPosition, toggleSourcePosition } = useHandlePositions(data);
12
+ return (_jsxs("div", { className: "p-[1px] rounded-lg max-w-[350px]", children: [_jsx("div", { className: "rounded-lg bg-background border-2 border-muted border-solid border-muted-foreground/10", "data-testid": `node-${title?.toLowerCase().replace(/ /g, '-')}`, children: _jsxs("div", { className: "group relative", children: [_jsxs(NodeHeader, { text: title, variant: variant, subtitle: subtitle, children: [_jsx(LanguageIndicator, { language: language }), _jsx("div", { className: "flex justify-end gap-2", children: _jsx("div", { className: "p-[2px] cursor-pointer rounded-md hover:bg-muted-foreground/10", onClick: () => setIsOpen(true), children: _jsx(ChevronUp, { className: "w-4 h-4" }) }) })] }), children && _jsx("div", { className: "border-t-2 border-muted-foreground/10 p-4 space-y-3", children: children }), !disableTargetHandle && (_jsx(BaseHandle, { type: "target", position: targetPosition, variant: variant, onTogglePosition: toggleTargetPosition })), !disableSourceHandle && (_jsx(BaseHandle, { type: "source", position: sourcePosition, variant: variant, onTogglePosition: toggleSourcePosition }))] }) }), _jsx(NodeSidebar, { title: title, subtitle: subtitle, variant: variant, language: language, isOpen: isOpen, onClose: () => setIsOpen(false), details: details, subscribes: subscribes, emits: emits })] }));
13
+ };
@@ -1,4 +1,4 @@
1
- import { EventNodeData } from '../views/flow/nodes/nodes.types';
1
+ import { EventNodeData } from '@/types/flow';
2
2
  import React from 'react';
3
3
  export declare const Emits: React.FC<{
4
4
  emits: EventNodeData['emits'];
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ const toTopic = (emit) => typeof emit === 'string' ? emit : emit.topic;
3
+ export const Emits = ({ emits }) => {
4
+ return (_jsx("div", { className: "flex flex-col gap-2", children: emits.map((emit) => (_jsx("div", { "data-testid": `emits__${toTopic(emit)}`, children: toTopic(emit) }, toTopic(emit)))) }));
5
+ };
@@ -1,5 +1,5 @@
1
+ import { EventNodeData } from '@/types/flow';
1
2
  import { FC } from 'react';
2
- import { EventNodeData } from './nodes.types';
3
3
  type Props = {
4
4
  language: EventNodeData['language'];
5
5
  };