@motiadev/workbench 0.6.0-beta.123 → 0.6.2-beta.125
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.
- package/dist/index.html +27 -17
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +22 -3
- package/dist/src/components/flow/node-organizer.js +39 -7
- package/dist/src/components/logs/log-level-dot.js +5 -5
- package/dist/src/components/tutorial/hooks/use-tutorial-engine.js +7 -1
- package/dist/src/hooks/use-update-handle-positions.js +2 -2
- package/dist/tsconfig.app.tsbuildinfo +1 -1
- package/dist/tsconfig.node.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/src/components/flow/hooks/use-organize-nodes.d.ts +0 -3
- package/dist/src/components/flow/hooks/use-organize-nodes.js +0 -43
package/dist/index.html
CHANGED
|
@@ -27,25 +27,35 @@
|
|
|
27
27
|
})
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
|
-
<!-- Start of Reo Javascript -->
|
|
31
|
-
<script type="text/javascript">
|
|
32
|
-
!(function () {
|
|
33
|
-
var e, t, n
|
|
34
|
-
;(e = 'd8f0ce9cae8ae64'),
|
|
35
|
-
(t = function () {
|
|
36
|
-
Reo.init({ clientID: 'd8f0ce9cae8ae64' })
|
|
37
|
-
}),
|
|
38
|
-
((n = document.createElement('script')).src = 'https://static.reo.dev/' + e + '/reo.js'),
|
|
39
|
-
(n.defer = !0),
|
|
40
|
-
(n.onload = t),
|
|
41
|
-
document.head.appendChild(n)
|
|
42
|
-
})()
|
|
43
|
-
</script>
|
|
44
|
-
<!-- End of Reo Javascript -->
|
|
45
|
-
|
|
46
30
|
<script>
|
|
47
31
|
const importFile = async (path) => {
|
|
48
|
-
|
|
32
|
+
// Normalize the path for cross-platform compatibility
|
|
33
|
+
const normalizedPath = path.replace(/\\/g, '/')
|
|
34
|
+
const fullPath = `${processCwd}/${normalizedPath}`.replace(/\\/g, '/')
|
|
35
|
+
|
|
36
|
+
// Handle Windows drive letters properly
|
|
37
|
+
let importPath = fullPath
|
|
38
|
+
if (navigator.platform.includes('Win')) {
|
|
39
|
+
// On Windows, ensure proper drive letter handling
|
|
40
|
+
if (fullPath.match(/^[A-Za-z]:/)) {
|
|
41
|
+
importPath = `/@fs/${fullPath}`
|
|
42
|
+
} else {
|
|
43
|
+
importPath = `/@fs/${fullPath}`
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
importPath = `/@fs/${fullPath}`
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
return await import(/* @vite-ignore */ importPath)
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error(`Failed to import ${path}:`, error)
|
|
53
|
+
// Return empty module if tutorial.tsx doesn't exist
|
|
54
|
+
if (path === 'tutorial.tsx') {
|
|
55
|
+
return { steps: [] }
|
|
56
|
+
}
|
|
57
|
+
throw error
|
|
58
|
+
}
|
|
49
59
|
}
|
|
50
60
|
</script>
|
|
51
61
|
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Express } from 'express';
|
|
2
|
-
export declare const applyMiddleware: (app: Express) => Promise<void>;
|
|
2
|
+
export declare const applyMiddleware: (app: Express, port: number) => Promise<void>;
|
package/dist/middleware.js
CHANGED
|
@@ -12,12 +12,30 @@ const processCwdPlugin = () => {
|
|
|
12
12
|
return {
|
|
13
13
|
name: 'html-transform',
|
|
14
14
|
transformIndexHtml: (html) => {
|
|
15
|
-
|
|
15
|
+
// Normalize path for cross-platform compatibility
|
|
16
|
+
const cwd = process.cwd().replace(/\\/g, '/');
|
|
16
17
|
return html.replace('</head>', `<script>const processCwd = "${cwd}";</script></head>`);
|
|
17
18
|
},
|
|
18
19
|
};
|
|
19
20
|
};
|
|
20
|
-
const
|
|
21
|
+
const reoPlugin = () => {
|
|
22
|
+
return {
|
|
23
|
+
name: 'html-transform',
|
|
24
|
+
transformIndexHtml(html) {
|
|
25
|
+
const isAnalyticsEnabled = process.env.MOTIA_ANALYTICS_DISABLED !== 'true';
|
|
26
|
+
if (!isAnalyticsEnabled) {
|
|
27
|
+
return html;
|
|
28
|
+
}
|
|
29
|
+
// inject before </head>
|
|
30
|
+
return html.replace('</head>', `
|
|
31
|
+
<script type="text/javascript">
|
|
32
|
+
!function(){var e,t,n;e="d8f0ce9cae8ae64",t=function(){Reo.init({clientID:"d8f0ce9cae8ae64", source: "internal"})},(n=document.createElement("script")).src="https://static.reo.dev/"+e+"/reo.js",n.defer=!0,n.onload=t,document.head.appendChild(n)}();
|
|
33
|
+
</script>
|
|
34
|
+
</head>`);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
const applyMiddleware = async (app, port) => {
|
|
21
39
|
const vite = await (0, vite_1.createServer)({
|
|
22
40
|
appType: 'spa',
|
|
23
41
|
root: __dirname,
|
|
@@ -25,6 +43,7 @@ const applyMiddleware = async (app) => {
|
|
|
25
43
|
middlewareMode: true,
|
|
26
44
|
allowedHosts: true,
|
|
27
45
|
host: true,
|
|
46
|
+
hmr: { port: 21678 + port },
|
|
28
47
|
fs: {
|
|
29
48
|
allow: [
|
|
30
49
|
__dirname, // workbench root
|
|
@@ -36,7 +55,7 @@ const applyMiddleware = async (app) => {
|
|
|
36
55
|
resolve: {
|
|
37
56
|
alias: { '@': path_1.default.resolve(__dirname, './src') },
|
|
38
57
|
},
|
|
39
|
-
plugins: [(0, plugin_react_1.default)(), processCwdPlugin()],
|
|
58
|
+
plugins: [(0, plugin_react_1.default)(), processCwdPlugin(), reoPlugin()],
|
|
40
59
|
});
|
|
41
60
|
app.use(vite.middlewares);
|
|
42
61
|
app.use('*', async (req, res, next) => {
|
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
import { useNodesInitialized, useReactFlow } from '@xyflow/react';
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
|
+
import dagre from 'dagre';
|
|
4
|
+
const organizeNodes = (nodes, edges) => {
|
|
5
|
+
const dagreGraph = new dagre.graphlib.Graph({ compound: true });
|
|
6
|
+
dagreGraph.setDefaultEdgeLabel(() => ({}));
|
|
7
|
+
dagreGraph.setGraph({ rankdir: 'LR', ranksep: 80, nodesep: 60, edgesep: 20, ranker: 'tight-tree' });
|
|
8
|
+
nodes.forEach((node) => {
|
|
9
|
+
dagreGraph.setNode(node.id, { width: node.measured?.width, height: node.measured?.height });
|
|
10
|
+
});
|
|
11
|
+
edges.forEach((edge) => {
|
|
12
|
+
if (typeof edge.label === 'string') {
|
|
13
|
+
dagreGraph.setEdge(edge.source, edge.target, {
|
|
14
|
+
label: edge.label ?? '',
|
|
15
|
+
width: edge.label.length * 40, // Add width for the label
|
|
16
|
+
height: 30, // Add height for the label
|
|
17
|
+
labelpos: 'c', // Position label in center
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
dagreGraph.setEdge(edge.source, edge.target);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
dagre.layout(dagreGraph);
|
|
25
|
+
return nodes.map((node) => {
|
|
26
|
+
if (node.position.x !== 0 || node.position.y !== 0) {
|
|
27
|
+
return node;
|
|
28
|
+
}
|
|
29
|
+
const { x, y } = dagreGraph.node(node.id);
|
|
30
|
+
const position = {
|
|
31
|
+
x: x - (node.measured?.width ?? 0) / 2,
|
|
32
|
+
y: y - (node.measured?.height ?? 0) / 2,
|
|
33
|
+
};
|
|
34
|
+
return { ...node, position };
|
|
35
|
+
});
|
|
36
|
+
};
|
|
3
37
|
export const NodeOrganizer = ({ onInitialized }) => {
|
|
4
38
|
const { setNodes, getNodes, getEdges, fitView } = useReactFlow();
|
|
5
39
|
const nodesInitialized = useNodesInitialized();
|
|
@@ -7,14 +41,12 @@ export const NodeOrganizer = ({ onInitialized }) => {
|
|
|
7
41
|
useEffect(() => {
|
|
8
42
|
if (nodesInitialized && !initialized.current) {
|
|
9
43
|
initialized.current = true;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
44
|
+
const nodes = getNodes();
|
|
45
|
+
const edges = getEdges();
|
|
46
|
+
const organizedNodes = organizeNodes(nodes, edges);
|
|
47
|
+
setNodes(organizedNodes);
|
|
14
48
|
onInitialized();
|
|
15
|
-
setTimeout(
|
|
16
|
-
await fitView();
|
|
17
|
-
}, 1);
|
|
49
|
+
setTimeout(() => fitView(), 1);
|
|
18
50
|
}
|
|
19
51
|
}, [nodesInitialized, onInitialized, setNodes, getNodes, getEdges, fitView]);
|
|
20
52
|
return null;
|
|
@@ -4,11 +4,11 @@ const badgeVariants = cva('text-xs font-medium tracking-wide rounded-full h-[6px
|
|
|
4
4
|
variants: {
|
|
5
5
|
variant: {
|
|
6
6
|
info: 'bg-[#2862FE] outline-[#2862FE]/20',
|
|
7
|
-
trace: 'bg-
|
|
8
|
-
debug: 'bg-
|
|
9
|
-
error: 'bg-
|
|
10
|
-
fatal: 'bg-
|
|
11
|
-
warn: 'bg-
|
|
7
|
+
trace: 'bg-[#2862FE] outline-[#2862FE]/20',
|
|
8
|
+
debug: 'bg-[#2862FE] outline-[#2862FE]/20',
|
|
9
|
+
error: 'bg-[#E22A6D] outline-[#E22A6D]/20',
|
|
10
|
+
fatal: 'bg-[#E22A6D] outline-[#E22A6D]/20',
|
|
11
|
+
warn: 'bg-[#F59F0B] outline-[#F59F0B]/20',
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
14
|
});
|
|
@@ -38,6 +38,7 @@ export const useTutorialEngine = () => {
|
|
|
38
38
|
// Run any before actions
|
|
39
39
|
if (step.before) {
|
|
40
40
|
for (const action of step.before) {
|
|
41
|
+
const monaco = window.monaco;
|
|
41
42
|
if (action.type === 'click') {
|
|
42
43
|
const element = await waitForElementByXPath(action.selector, action.optional);
|
|
43
44
|
if (element) {
|
|
@@ -131,10 +132,15 @@ export const useTutorialEngine = () => {
|
|
|
131
132
|
}
|
|
132
133
|
};
|
|
133
134
|
useEffect(() => {
|
|
134
|
-
importFile('tutorial.tsx')
|
|
135
|
+
importFile('tutorial.tsx')
|
|
136
|
+
.then((module) => {
|
|
135
137
|
if (Array.isArray(module.steps) && module.steps.length > 0) {
|
|
136
138
|
MotiaTutorial.register(module.steps);
|
|
137
139
|
}
|
|
140
|
+
})
|
|
141
|
+
.catch((error) => {
|
|
142
|
+
// Tutorial file is optional, so we don't need to throw an error
|
|
143
|
+
console.log('Tutorial file not found or could not be loaded:', error.message);
|
|
138
144
|
});
|
|
139
145
|
}, []);
|
|
140
146
|
useEffect(() => {
|
|
@@ -2,8 +2,8 @@ import { Position, useReactFlow, useUpdateNodeInternals } from '@xyflow/react';
|
|
|
2
2
|
export const useHandlePositions = (data) => {
|
|
3
3
|
const reactFlow = useReactFlow();
|
|
4
4
|
const updateNodeInternals = useUpdateNodeInternals();
|
|
5
|
-
const sourcePosition = data.nodeConfig?.sourceHandlePosition === '
|
|
6
|
-
const targetPosition = data.nodeConfig?.targetHandlePosition === '
|
|
5
|
+
const sourcePosition = data.nodeConfig?.sourceHandlePosition === 'bottom' ? Position.Bottom : Position.Right;
|
|
6
|
+
const targetPosition = data.nodeConfig?.targetHandlePosition === 'top' ? Position.Top : Position.Left;
|
|
7
7
|
const updateSourcePosition = (position) => {
|
|
8
8
|
reactFlow.updateNode(data.id, {
|
|
9
9
|
data: { ...data, nodeConfig: { ...data.nodeConfig, sourceHandlePosition: position } },
|