@rozenite/vite-plugin 1.13.0 → 2.1.0
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/README.md +12 -0
- package/dist/bundle-dts.d.ts.map +1 -1
- package/dist/client-plugin.d.ts.map +1 -1
- package/dist/dev-host/assets/index-BgAxGQdD.js +13 -0
- package/dist/dev-host/assets/index-ClIYIppU.css +1 -0
- package/dist/dev-host/index.html +3 -3
- package/dist/dev-host/manifest.json +2 -2
- package/dist/index.cjs +34 -63
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -63
- package/dist/load-config.d.ts.map +1 -1
- package/dist/package-json.d.ts.map +1 -1
- package/dist/react-native-plugin.d.ts.map +1 -1
- package/dist/require-plugin.d.ts.map +1 -1
- package/dist/sdk-plugin.d.ts.map +1 -1
- package/dist/server-plugin.d.ts.map +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +29 -30
- package/src/bundle-dts.ts +6 -14
- package/src/client-plugin.ts +13 -36
- package/src/dev-host/App.tsx +184 -414
- package/src/dev-host/components/DispatchForm.tsx +97 -121
- package/src/dev-host/components/FlowList.tsx +70 -102
- package/src/dev-host/components/MessageDetailsPane.tsx +50 -83
- package/src/dev-host/components/MessageLogPane.tsx +75 -66
- package/src/dev-host/components/PanelTabs.tsx +19 -10
- package/src/dev-host/constants.ts +0 -19
- package/src/dev-host/flow-runtime.ts +15 -12
- package/src/dev-host/index.html +1 -1
- package/src/dev-host/main.tsx +1 -10
- package/src/dev-host/styles.css +162 -830
- package/src/dev-host/types.ts +0 -9
- package/src/dev-host/utils.ts +1 -7
- package/src/dev-host/vite.config.mts +2 -0
- package/src/index.ts +16 -16
- package/src/load-config.ts +9 -20
- package/src/package-json.ts +1 -3
- package/src/react-native-plugin.ts +4 -2
- package/src/require-plugin.ts +6 -18
- package/src/sdk-plugin.ts +3 -0
- package/src/server-plugin.ts +3 -0
- package/src/utils.ts +1 -4
- package/dist/dev-host/assets/index-CkxvBMpp.css +0 -1
- package/dist/dev-host/assets/index-cNKHRwej.js +0 -11
- package/src/dev-host/components/MessagePayloadDetail.tsx +0 -32
- package/src/dev-host/components/ResizeHandle.tsx +0 -33
- package/src/dev-host/components/icons.tsx +0 -79
- package/src/dev-host/components/ui/Button.tsx +0 -91
- package/src/dev-host/components/ui/DropdownMenu.tsx +0 -84
- package/src/dev-host/components/ui/IconButton.tsx +0 -41
- package/src/dev-host/components/ui/Input.tsx +0 -73
- package/src/dev-host/components/ui/ScrollArea.tsx +0 -20
- package/src/dev-host/components/ui/Tabs.tsx +0 -166
- package/src/dev-host/components/ui/Textarea.tsx +0 -79
- package/src/dev-host/components/ui/ToggleGroup.tsx +0 -120
package/src/dev-host/App.tsx
CHANGED
|
@@ -1,34 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
useRef,
|
|
4
|
-
useState,
|
|
5
|
-
type CSSProperties,
|
|
6
|
-
type FormEvent,
|
|
7
|
-
type PointerEvent as ReactPointerEvent,
|
|
8
|
-
} from 'react';
|
|
9
|
-
import {
|
|
10
|
-
DEFAULT_COMMAND_WIDTH,
|
|
11
|
-
DEFAULT_DEVTOOLS_HEIGHT,
|
|
12
|
-
DETAILS_PANEL_WIDTH,
|
|
13
|
-
MIN_COMMAND_WIDTH,
|
|
14
|
-
MIN_DETAILS_WIDTH,
|
|
15
|
-
MIN_DEVTOOLS_HEIGHT,
|
|
16
|
-
MIN_IFRAME_HEIGHT,
|
|
17
|
-
MIN_NARROW_IFRAME_HEIGHT,
|
|
18
|
-
SPLITTER_SIZE,
|
|
19
|
-
} from './constants.js';
|
|
1
|
+
import { useEffect, useRef, useState, type FormEvent } from 'react';
|
|
2
|
+
import { PluginHeader, PluginShell, Split, Tabs } from '@rozenite/ui';
|
|
20
3
|
import type {
|
|
21
4
|
DevHostFlowEntry,
|
|
22
5
|
DevHostPanelEntry,
|
|
23
6
|
DevHostPresetEntry,
|
|
24
7
|
DevHostState,
|
|
25
8
|
MessageEntry,
|
|
26
|
-
ResizeHandleId,
|
|
27
|
-
ResizeSession,
|
|
28
9
|
} from './types.js';
|
|
29
10
|
import { useFlowRunner } from './flow-runtime.js';
|
|
30
11
|
import {
|
|
31
|
-
clamp,
|
|
32
12
|
createMessageEntry,
|
|
33
13
|
formatPayloadForCommandInput,
|
|
34
14
|
getInitialPanel,
|
|
@@ -41,11 +21,7 @@ import {
|
|
|
41
21
|
} from './components/MessageDetailsPane.js';
|
|
42
22
|
import { MessageLogPane } from './components/MessageLogPane.js';
|
|
43
23
|
import { PanelTabs } from './components/PanelTabs.js';
|
|
44
|
-
import
|
|
45
|
-
import { ToggleGroup } from './components/ui/ToggleGroup.js';
|
|
46
|
-
import { RozeniteLogo } from './components/icons.js';
|
|
47
|
-
|
|
48
|
-
type CSSVariables = CSSProperties & Record<`--${string}`, string>;
|
|
24
|
+
import './styles.css';
|
|
49
25
|
|
|
50
26
|
type AppProps = DevHostState & {
|
|
51
27
|
flows: DevHostFlowEntry[];
|
|
@@ -54,74 +30,67 @@ type AppProps = DevHostState & {
|
|
|
54
30
|
|
|
55
31
|
type MobileDevtoolsTab = 'log' | 'actions';
|
|
56
32
|
|
|
57
|
-
const
|
|
58
|
-
|
|
33
|
+
const useNarrowViewport = () => {
|
|
34
|
+
const [isNarrow, setIsNarrow] = useState(() => window.matchMedia('(max-width: 960px)').matches);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
const mediaQuery = window.matchMedia('(max-width: 960px)');
|
|
38
|
+
const handleChange = (event: MediaQueryListEvent) => {
|
|
39
|
+
setIsNarrow(event.matches);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
setIsNarrow(mediaQuery.matches);
|
|
43
|
+
mediaQuery.addEventListener('change', handleChange);
|
|
44
|
+
|
|
45
|
+
return () => mediaQuery.removeEventListener('change', handleChange);
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
return isNarrow;
|
|
59
49
|
};
|
|
60
50
|
|
|
61
51
|
export const App = ({ packageName, packageDescription, panels, flows, presets }: AppProps) => {
|
|
62
|
-
const [activePanel, setActivePanel] = useState<DevHostPanelEntry | null>(() =>
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
const [activePanel, setActivePanel] = useState<DevHostPanelEntry | null>(() =>
|
|
53
|
+
getInitialPanel(panels),
|
|
54
|
+
);
|
|
65
55
|
const [commandType, setCommandType] = useState('');
|
|
66
56
|
const [commandPayload, setCommandPayload] = useState('');
|
|
67
57
|
const [messages, setMessages] = useState<MessageEntry[]>([]);
|
|
68
58
|
const [selectedMessageId, setSelectedMessageId] = useState<string | null>(null);
|
|
69
59
|
const [isDetailsOpen, setIsDetailsOpen] = useState(false);
|
|
70
|
-
const [devToolsHeight, setDevToolsHeight] = useState(DEFAULT_DEVTOOLS_HEIGHT);
|
|
71
|
-
const [commandWidth, setCommandWidth] = useState(DEFAULT_COMMAND_WIDTH);
|
|
72
|
-
const [detailsWidth, setDetailsWidth] = useState(DETAILS_PANEL_WIDTH);
|
|
73
|
-
const [activeResizeHandle, setActiveResizeHandle] = useState<ResizeHandleId | null>(null);
|
|
74
|
-
const [isNarrowViewport, setIsNarrowViewport] = useState(getViewportMatch);
|
|
75
60
|
const [activeMobileTab, setActiveMobileTab] = useState<MobileDevtoolsTab>('log');
|
|
76
61
|
const [iframeLoadNonce, setIframeLoadNonce] = useState(0);
|
|
77
|
-
const workspaceRef = useRef<HTMLElement | null>(null);
|
|
78
|
-
const logWorkspaceRef = useRef<HTMLDivElement | null>(null);
|
|
79
|
-
const devtoolsRef = useRef<HTMLElement | null>(null);
|
|
80
|
-
const resizeSessionRef = useRef<ResizeSession | null>(null);
|
|
81
62
|
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
|
82
63
|
const lastAutoRunLoadRef = useRef(0);
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
type,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
'
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
appendMessage({
|
|
95
|
-
direction: 'in',
|
|
96
|
-
type,
|
|
97
|
-
payload,
|
|
98
|
-
});
|
|
99
|
-
},
|
|
100
|
-
});
|
|
64
|
+
const isNarrowViewport = useNarrowViewport();
|
|
65
|
+
const { flowRuns, runFlow, stopFlow, hasRunningFlow, registerMessage, resetMessages } =
|
|
66
|
+
useFlowRunner({
|
|
67
|
+
sendMessage: (type, payload) => {
|
|
68
|
+
iframeRef.current?.contentWindow?.postMessage(
|
|
69
|
+
{ pluginId: packageName, type, payload },
|
|
70
|
+
'*',
|
|
71
|
+
);
|
|
72
|
+
appendMessage({ direction: 'in', type, payload });
|
|
73
|
+
},
|
|
74
|
+
});
|
|
101
75
|
|
|
102
76
|
const activeSource = activePanel?.source ?? '';
|
|
103
77
|
const activeLabel = activePanel?.label ?? '';
|
|
104
|
-
const emptyState = panels.length === 0;
|
|
105
78
|
const selectedMessage = messages.find((message) => message.id === selectedMessageId) ?? null;
|
|
79
|
+
const panelDescription = packageDescription.trim();
|
|
106
80
|
const trimmedCommandType = commandType.trim();
|
|
107
81
|
const trimmedCommandPayload = commandPayload.trim();
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
if (!trimmedCommandPayload) {
|
|
82
|
+
const canDispatch = (() => {
|
|
83
|
+
if (!trimmedCommandType || !trimmedCommandPayload) {
|
|
111
84
|
return false;
|
|
112
85
|
}
|
|
113
86
|
|
|
114
87
|
try {
|
|
115
|
-
JSON.parse(
|
|
88
|
+
JSON.parse(trimmedCommandPayload);
|
|
116
89
|
return true;
|
|
117
90
|
} catch {
|
|
118
91
|
return false;
|
|
119
92
|
}
|
|
120
93
|
})();
|
|
121
|
-
const canDispatch = hasCommandType && hasValidCommandPayload;
|
|
122
|
-
const panelDescription = packageDescription.trim();
|
|
123
|
-
const isDetailsVisible = isDetailsOpen && selectedMessage !== null;
|
|
124
|
-
const iframeMinHeight = isNarrowViewport ? MIN_NARROW_IFRAME_HEIGHT : MIN_IFRAME_HEIGHT;
|
|
125
94
|
|
|
126
95
|
useEffect(() => {
|
|
127
96
|
document.title = `${packageName} Dev Host`;
|
|
@@ -145,106 +114,6 @@ export const App = ({ packageName, packageDescription, panels, flows, presets }:
|
|
|
145
114
|
});
|
|
146
115
|
}, [flows, iframeLoadNonce, runFlow]);
|
|
147
116
|
|
|
148
|
-
useEffect(() => {
|
|
149
|
-
const mediaQuery = window.matchMedia('(max-width: 960px)');
|
|
150
|
-
|
|
151
|
-
const handleChange = (event: MediaQueryListEvent) => {
|
|
152
|
-
setIsNarrowViewport(event.matches);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
setIsNarrowViewport(mediaQuery.matches);
|
|
156
|
-
mediaQuery.addEventListener('change', handleChange);
|
|
157
|
-
|
|
158
|
-
return () => {
|
|
159
|
-
mediaQuery.removeEventListener('change', handleChange);
|
|
160
|
-
};
|
|
161
|
-
}, []);
|
|
162
|
-
|
|
163
|
-
useEffect(() => {
|
|
164
|
-
const workspace = workspaceRef.current;
|
|
165
|
-
if (!workspace) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const bounds = workspace.getBoundingClientRect();
|
|
170
|
-
const maxHeight = Math.max(MIN_DEVTOOLS_HEIGHT, bounds.height - iframeMinHeight - 12);
|
|
171
|
-
|
|
172
|
-
setDevToolsHeight((current) => clamp(current, MIN_DEVTOOLS_HEIGHT, maxHeight));
|
|
173
|
-
}, [iframeMinHeight]);
|
|
174
|
-
|
|
175
|
-
useEffect(() => {
|
|
176
|
-
if (!isNarrowViewport) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
setActiveMobileTab('log');
|
|
181
|
-
}, [isNarrowViewport]);
|
|
182
|
-
|
|
183
|
-
const selectPanel = (value: string) => {
|
|
184
|
-
const nextPanel = panels.find((panel) => panel.source === value);
|
|
185
|
-
if (!nextPanel) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
setActivePanel(nextPanel);
|
|
190
|
-
const nextUrl = new URL(window.location.href);
|
|
191
|
-
nextUrl.searchParams.set('panel', nextPanel.label);
|
|
192
|
-
window.history.replaceState(null, '', nextUrl);
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const appendMessage = (input: Omit<MessageEntry, 'id' | 'date'>) => {
|
|
196
|
-
const nextEntry = createMessageEntry(input);
|
|
197
|
-
|
|
198
|
-
registerMessage(nextEntry);
|
|
199
|
-
setMessages((current) => [nextEntry, ...current]);
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
useEffect(() => {
|
|
203
|
-
const handlePointerMove = (event: PointerEvent) => {
|
|
204
|
-
resizeSessionRef.current?.onMove(event);
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
const stopDragging = () => {
|
|
208
|
-
const session = resizeSessionRef.current;
|
|
209
|
-
if (!session) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
if (session.element.hasPointerCapture(session.pointerId)) {
|
|
214
|
-
session.element.releasePointerCapture(session.pointerId);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
resizeSessionRef.current = null;
|
|
218
|
-
setActiveResizeHandle(null);
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
window.addEventListener('pointermove', handlePointerMove);
|
|
222
|
-
window.addEventListener('pointerup', stopDragging);
|
|
223
|
-
window.addEventListener('pointercancel', stopDragging);
|
|
224
|
-
|
|
225
|
-
return () => {
|
|
226
|
-
window.removeEventListener('pointermove', handlePointerMove);
|
|
227
|
-
window.removeEventListener('pointerup', stopDragging);
|
|
228
|
-
window.removeEventListener('pointercancel', stopDragging);
|
|
229
|
-
};
|
|
230
|
-
}, []);
|
|
231
|
-
|
|
232
|
-
const startResize = (
|
|
233
|
-
handleId: ResizeHandleId,
|
|
234
|
-
event: ReactPointerEvent<HTMLDivElement>,
|
|
235
|
-
onMove: (event: PointerEvent) => void,
|
|
236
|
-
) => {
|
|
237
|
-
event.preventDefault();
|
|
238
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
239
|
-
resizeSessionRef.current = {
|
|
240
|
-
handleId,
|
|
241
|
-
pointerId: event.pointerId,
|
|
242
|
-
element: event.currentTarget,
|
|
243
|
-
onMove,
|
|
244
|
-
};
|
|
245
|
-
setActiveResizeHandle(handleId);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
117
|
useEffect(() => {
|
|
249
118
|
const handleMessage = (event: MessageEvent) => {
|
|
250
119
|
if (event.source !== iframeRef.current?.contentWindow) {
|
|
@@ -254,19 +123,14 @@ export const App = ({ packageName, packageDescription, panels, flows, presets }:
|
|
|
254
123
|
if (
|
|
255
124
|
typeof event.data !== 'object' ||
|
|
256
125
|
event.data === null ||
|
|
257
|
-
!('type' in event.data) ||
|
|
258
126
|
event.data.type !== 'rozenite-message' ||
|
|
259
|
-
!('payload' in event.data)
|
|
127
|
+
!('payload' in event.data) ||
|
|
128
|
+
!isPluginMessage(event.data.payload)
|
|
260
129
|
) {
|
|
261
130
|
return;
|
|
262
131
|
}
|
|
263
132
|
|
|
264
133
|
const payload = event.data.payload;
|
|
265
|
-
|
|
266
|
-
if (!isPluginMessage(payload)) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
134
|
appendMessage({
|
|
271
135
|
direction: 'out',
|
|
272
136
|
type: payload.type,
|
|
@@ -275,20 +139,25 @@ export const App = ({ packageName, packageDescription, panels, flows, presets }:
|
|
|
275
139
|
};
|
|
276
140
|
|
|
277
141
|
window.addEventListener('message', handleMessage);
|
|
278
|
-
|
|
279
|
-
return () => {
|
|
280
|
-
window.removeEventListener('message', handleMessage);
|
|
281
|
-
};
|
|
142
|
+
return () => window.removeEventListener('message', handleMessage);
|
|
282
143
|
}, []);
|
|
283
144
|
|
|
284
|
-
const
|
|
285
|
-
|
|
286
|
-
|
|
145
|
+
const appendMessage = (input: Omit<MessageEntry, 'id' | 'date'>) => {
|
|
146
|
+
const nextEntry = createMessageEntry(input);
|
|
147
|
+
registerMessage(nextEntry);
|
|
148
|
+
setMessages((current) => [nextEntry, ...current]);
|
|
287
149
|
};
|
|
288
150
|
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
151
|
+
const selectPanel = (value: string) => {
|
|
152
|
+
const nextPanel = panels.find((panel) => panel.source === value);
|
|
153
|
+
if (!nextPanel) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
setActivePanel(nextPanel);
|
|
158
|
+
const nextUrl = new URL(window.location.href);
|
|
159
|
+
nextUrl.searchParams.set('panel', nextPanel.label);
|
|
160
|
+
window.history.replaceState(null, '', nextUrl);
|
|
292
161
|
};
|
|
293
162
|
|
|
294
163
|
const clearMessages = () => {
|
|
@@ -299,269 +168,170 @@ export const App = ({ packageName, packageDescription, panels, flows, presets }:
|
|
|
299
168
|
setActiveMobileTab('log');
|
|
300
169
|
};
|
|
301
170
|
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const bounds = workspace.getBoundingClientRect();
|
|
309
|
-
const nextHeight = bounds.bottom - event.clientY;
|
|
310
|
-
const maxHeight = Math.max(MIN_DEVTOOLS_HEIGHT, bounds.height - iframeMinHeight - 12);
|
|
311
|
-
|
|
312
|
-
setDevToolsHeight(clamp(nextHeight, MIN_DEVTOOLS_HEIGHT, maxHeight));
|
|
171
|
+
const resetForm = () => {
|
|
172
|
+
setCommandType('');
|
|
173
|
+
setCommandPayload('');
|
|
313
174
|
};
|
|
314
175
|
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const bounds = devtools.getBoundingClientRect();
|
|
322
|
-
const nextWidth = bounds.right - event.clientX;
|
|
323
|
-
const maxWidth = Math.max(MIN_COMMAND_WIDTH, bounds.width - 280);
|
|
324
|
-
|
|
325
|
-
setCommandWidth(clamp(nextWidth, MIN_COMMAND_WIDTH, maxWidth));
|
|
176
|
+
const applyPreset = (preset: DevHostPresetEntry) => {
|
|
177
|
+
setCommandType(preset.type);
|
|
178
|
+
setCommandPayload(formatPayloadForCommandInput(preset.payload));
|
|
326
179
|
};
|
|
327
180
|
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
if (!
|
|
181
|
+
const handleDispatch = (event: FormEvent<HTMLFormElement>) => {
|
|
182
|
+
event.preventDefault();
|
|
183
|
+
if (!canDispatch) {
|
|
331
184
|
return;
|
|
332
185
|
}
|
|
333
186
|
|
|
334
|
-
const
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
187
|
+
const payload = JSON.parse(trimmedCommandPayload) as unknown;
|
|
188
|
+
iframeRef.current?.contentWindow?.postMessage(
|
|
189
|
+
{ pluginId: packageName, type: trimmedCommandType, payload },
|
|
190
|
+
'*',
|
|
191
|
+
);
|
|
192
|
+
appendMessage({
|
|
193
|
+
direction: 'in',
|
|
194
|
+
type: trimmedCommandType,
|
|
195
|
+
payload,
|
|
196
|
+
});
|
|
197
|
+
resetForm();
|
|
339
198
|
};
|
|
340
199
|
|
|
341
200
|
const handleMessageSelect = (messageId: string) => {
|
|
342
201
|
setSelectedMessageId(messageId);
|
|
343
202
|
setIsDetailsOpen(true);
|
|
344
|
-
|
|
345
203
|
if (isNarrowViewport) {
|
|
346
204
|
setActiveMobileTab('log');
|
|
347
205
|
}
|
|
348
206
|
};
|
|
349
207
|
|
|
350
|
-
const
|
|
208
|
+
const useMessage = (message: MessageEntry) => {
|
|
209
|
+
const nextValues = getDispatcherValuesFromMessage(message);
|
|
210
|
+
setCommandType(nextValues.commandType);
|
|
211
|
+
setCommandPayload(nextValues.commandPayload);
|
|
351
212
|
setIsDetailsOpen(false);
|
|
352
|
-
|
|
353
213
|
if (isNarrowViewport) {
|
|
354
|
-
setActiveMobileTab('
|
|
214
|
+
setActiveMobileTab('actions');
|
|
355
215
|
}
|
|
356
216
|
};
|
|
357
217
|
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (!canDispatch) {
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const type = trimmedCommandType;
|
|
371
|
-
|
|
372
|
-
let payload: unknown;
|
|
373
|
-
|
|
374
|
-
try {
|
|
375
|
-
payload = JSON.parse(commandPayload);
|
|
376
|
-
} catch (error) {
|
|
377
|
-
window.alert(
|
|
378
|
-
error instanceof Error
|
|
379
|
-
? `Payload must be valid JSON. ${error.message}`
|
|
380
|
-
: 'Payload must be valid JSON.',
|
|
381
|
-
);
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
iframeRef.current?.contentWindow?.postMessage({ pluginId: packageName, type, payload }, '*');
|
|
218
|
+
const messageLog = (
|
|
219
|
+
<MessageLogPane
|
|
220
|
+
messages={messages}
|
|
221
|
+
onSelectMessage={handleMessageSelect}
|
|
222
|
+
onClearMessages={clearMessages}
|
|
223
|
+
/>
|
|
224
|
+
);
|
|
386
225
|
|
|
387
|
-
|
|
226
|
+
const actions = (
|
|
227
|
+
<DispatchForm
|
|
228
|
+
commandType={commandType}
|
|
229
|
+
commandPayload={commandPayload}
|
|
230
|
+
flows={flows}
|
|
231
|
+
flowRuns={flowRuns}
|
|
232
|
+
hasRunningFlow={hasRunningFlow}
|
|
233
|
+
presets={presets}
|
|
234
|
+
canDispatch={canDispatch}
|
|
235
|
+
onRunFlow={runFlow}
|
|
236
|
+
onStopFlow={stopFlow}
|
|
237
|
+
onCommandTypeChange={setCommandType}
|
|
238
|
+
onCommandPayloadChange={setCommandPayload}
|
|
239
|
+
onApplyPreset={applyPreset}
|
|
240
|
+
onReset={resetForm}
|
|
241
|
+
onSubmit={handleDispatch}
|
|
242
|
+
/>
|
|
243
|
+
);
|
|
388
244
|
|
|
389
|
-
|
|
390
|
-
|
|
245
|
+
const devtools = isNarrowViewport ? (
|
|
246
|
+
<Tabs
|
|
247
|
+
className="dev-host-mobile-tabs"
|
|
248
|
+
value={activeMobileTab}
|
|
249
|
+
onValueChange={(value) => setActiveMobileTab(value as MobileDevtoolsTab)}
|
|
250
|
+
>
|
|
251
|
+
<Tabs.List className="dev-host-mobile-tab-list" aria-label="DevTools sections">
|
|
252
|
+
<Tabs.Tab value="log">Log</Tabs.Tab>
|
|
253
|
+
<Tabs.Tab value="actions">Actions</Tabs.Tab>
|
|
254
|
+
</Tabs.List>
|
|
255
|
+
<Tabs.Panel value="log" className="dev-host-mobile-tab-panel">
|
|
256
|
+
{isDetailsOpen && selectedMessage ? (
|
|
257
|
+
<MessageDetailsPane
|
|
258
|
+
selectedMessage={selectedMessage}
|
|
259
|
+
onClose={() => setIsDetailsOpen(false)}
|
|
260
|
+
onUseMessage={useMessage}
|
|
261
|
+
/>
|
|
262
|
+
) : (
|
|
263
|
+
messageLog
|
|
264
|
+
)}
|
|
265
|
+
</Tabs.Panel>
|
|
266
|
+
<Tabs.Panel value="actions" className="dev-host-mobile-tab-panel">
|
|
267
|
+
{actions}
|
|
268
|
+
</Tabs.Panel>
|
|
269
|
+
</Tabs>
|
|
270
|
+
) : (
|
|
271
|
+
<Split direction="horizontal" className="dev-host-devtools">
|
|
272
|
+
<Split.Pane minSize={35}>
|
|
273
|
+
{isDetailsOpen && selectedMessage ? (
|
|
274
|
+
<Split direction="horizontal">
|
|
275
|
+
<Split.Pane minSize={55}>{messageLog}</Split.Pane>
|
|
276
|
+
<Split.Handle />
|
|
277
|
+
<Split.Pane defaultSize={30} minSize={20}>
|
|
278
|
+
<MessageDetailsPane
|
|
279
|
+
selectedMessage={selectedMessage}
|
|
280
|
+
onClose={() => setIsDetailsOpen(false)}
|
|
281
|
+
onUseMessage={useMessage}
|
|
282
|
+
/>
|
|
283
|
+
</Split.Pane>
|
|
284
|
+
</Split>
|
|
285
|
+
) : (
|
|
286
|
+
messageLog
|
|
287
|
+
)}
|
|
288
|
+
</Split.Pane>
|
|
289
|
+
<Split.Handle />
|
|
290
|
+
<Split.Pane defaultSize={28} minSize={20}>
|
|
291
|
+
{actions}
|
|
292
|
+
</Split.Pane>
|
|
293
|
+
</Split>
|
|
294
|
+
);
|
|
391
295
|
|
|
392
296
|
return (
|
|
393
|
-
<
|
|
394
|
-
<
|
|
395
|
-
<div className="
|
|
396
|
-
<
|
|
297
|
+
<PluginShell className="dev-host">
|
|
298
|
+
<PluginHeader className="dev-host-header">
|
|
299
|
+
<div className="dev-host-header-title">
|
|
300
|
+
<PluginHeader.Title>Rozenite Dev Host</PluginHeader.Title>
|
|
301
|
+
<PluginHeader.Subtitle className="dev-host-header-subtitle" title={panelDescription}>
|
|
302
|
+
{packageName}
|
|
303
|
+
</PluginHeader.Subtitle>
|
|
397
304
|
</div>
|
|
398
|
-
|
|
399
|
-
|
|
305
|
+
<PluginHeader.Actions>
|
|
306
|
+
<PluginHeader.ThemeSwitcher />
|
|
400
307
|
<PanelTabs panels={panels} activeSource={activeSource} onValueChange={selectPanel} />
|
|
401
|
-
</
|
|
402
|
-
</
|
|
403
|
-
|
|
404
|
-
<
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
) : (
|
|
308
|
+
</PluginHeader.Actions>
|
|
309
|
+
</PluginHeader>
|
|
310
|
+
|
|
311
|
+
<PluginShell.Body className="dev-host-body">
|
|
312
|
+
<Split direction="vertical" className="dev-host-main-split" autoSaveId="dev-host">
|
|
313
|
+
<Split.Pane defaultSize={64} minSize={30} className="dev-host-preview">
|
|
314
|
+
{panels.length === 0 ? (
|
|
315
|
+
<div className="flex h-full items-center justify-center p-8 text-center text-sm text-muted-foreground">
|
|
316
|
+
No panels were defined in rozenite.config.ts.
|
|
317
|
+
</div>
|
|
318
|
+
) : (
|
|
413
319
|
<iframe
|
|
414
320
|
key={activeSource}
|
|
415
321
|
ref={iframeRef}
|
|
416
322
|
title={activeLabel || 'Rozenite panel preview'}
|
|
417
323
|
src={activeSource}
|
|
418
|
-
className="
|
|
419
|
-
data-resizing={activeResizeHandle === 'devtools-height'}
|
|
324
|
+
className="dev-host-iframe"
|
|
420
325
|
onLoad={() => setIframeLoadNonce((value) => value + 1)}
|
|
421
326
|
/>
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
/>
|
|
432
|
-
|
|
433
|
-
{isNarrowViewport ? (
|
|
434
|
-
<section ref={devtoolsRef} className="rz-devtools-mobile">
|
|
435
|
-
<div className="rz-devtools-mobile-tabs">
|
|
436
|
-
<div className="rz-devtools-mobile-toggle">
|
|
437
|
-
<ToggleGroup
|
|
438
|
-
aria-label="DevTools sections"
|
|
439
|
-
value={activeMobileTab}
|
|
440
|
-
onChange={handleMobileTabChange}
|
|
441
|
-
options={[
|
|
442
|
-
{ key: 'log', label: 'Log' },
|
|
443
|
-
{ key: 'actions', label: 'Actions' },
|
|
444
|
-
]}
|
|
445
|
-
/>
|
|
446
|
-
</div>
|
|
447
|
-
|
|
448
|
-
<div className="rz-devtools-mobile-panel">
|
|
449
|
-
{activeMobileTab === 'log' ? (
|
|
450
|
-
isDetailsVisible ? (
|
|
451
|
-
<MessageDetailsPane
|
|
452
|
-
selectedMessage={selectedMessage}
|
|
453
|
-
isOpen={true}
|
|
454
|
-
isNarrowViewport={true}
|
|
455
|
-
activeResizeHandle={activeResizeHandle}
|
|
456
|
-
onClose={handleDetailsClose}
|
|
457
|
-
onUseMessage={(message) => {
|
|
458
|
-
const nextValues = getDispatcherValuesFromMessage(message);
|
|
459
|
-
setCommandType(nextValues.commandType);
|
|
460
|
-
setCommandPayload(nextValues.commandPayload);
|
|
461
|
-
setIsDetailsOpen(false);
|
|
462
|
-
setActiveMobileTab('actions');
|
|
463
|
-
}}
|
|
464
|
-
onResizeStart={(event) => startResize('details-width', event, resizeDetailsPane)}
|
|
465
|
-
/>
|
|
466
|
-
) : (
|
|
467
|
-
<MessageLogPane
|
|
468
|
-
messages={messages}
|
|
469
|
-
selectedMessageId={selectedMessageId}
|
|
470
|
-
onSelectMessage={handleMessageSelect}
|
|
471
|
-
onClearMessages={clearMessages}
|
|
472
|
-
/>
|
|
473
|
-
)
|
|
474
|
-
) : (
|
|
475
|
-
<DispatchForm
|
|
476
|
-
commandType={commandType}
|
|
477
|
-
commandPayload={commandPayload}
|
|
478
|
-
flows={flows}
|
|
479
|
-
flowRuns={flowRuns}
|
|
480
|
-
hasRunningFlow={hasRunningFlow}
|
|
481
|
-
presets={presets}
|
|
482
|
-
canDispatch={canDispatch}
|
|
483
|
-
onRunFlow={runFlow}
|
|
484
|
-
onStopFlow={stopFlow}
|
|
485
|
-
onCommandTypeChange={setCommandType}
|
|
486
|
-
onCommandPayloadChange={setCommandPayload}
|
|
487
|
-
onApplyPreset={applyPreset}
|
|
488
|
-
onReset={resetForm}
|
|
489
|
-
onSubmit={handleDispatch}
|
|
490
|
-
/>
|
|
491
|
-
)}
|
|
492
|
-
</div>
|
|
493
|
-
</div>
|
|
494
|
-
</section>
|
|
495
|
-
) : (
|
|
496
|
-
<section
|
|
497
|
-
ref={devtoolsRef}
|
|
498
|
-
className="rz-devtools"
|
|
499
|
-
style={
|
|
500
|
-
{
|
|
501
|
-
'--rz-command-width': `${commandWidth}px`,
|
|
502
|
-
'--rz-command-splitter-width': `${SPLITTER_SIZE}px`,
|
|
503
|
-
} as CSSVariables
|
|
504
|
-
}
|
|
505
|
-
>
|
|
506
|
-
<div
|
|
507
|
-
ref={logWorkspaceRef}
|
|
508
|
-
className="rz-log-workspace"
|
|
509
|
-
style={
|
|
510
|
-
{
|
|
511
|
-
'--rz-details-width': isDetailsVisible ? `${detailsWidth}px` : '0px',
|
|
512
|
-
'--rz-details-splitter-width': isDetailsVisible ? `${SPLITTER_SIZE}px` : '0px',
|
|
513
|
-
} as CSSVariables
|
|
514
|
-
}
|
|
515
|
-
>
|
|
516
|
-
<MessageLogPane
|
|
517
|
-
messages={messages}
|
|
518
|
-
selectedMessageId={selectedMessageId}
|
|
519
|
-
onSelectMessage={handleMessageSelect}
|
|
520
|
-
onClearMessages={clearMessages}
|
|
521
|
-
/>
|
|
522
|
-
|
|
523
|
-
<MessageDetailsPane
|
|
524
|
-
selectedMessage={selectedMessage}
|
|
525
|
-
isOpen={isDetailsOpen}
|
|
526
|
-
isNarrowViewport={false}
|
|
527
|
-
activeResizeHandle={activeResizeHandle}
|
|
528
|
-
onClose={handleDetailsClose}
|
|
529
|
-
onUseMessage={(message) => {
|
|
530
|
-
const nextValues = getDispatcherValuesFromMessage(message);
|
|
531
|
-
setCommandType(nextValues.commandType);
|
|
532
|
-
setCommandPayload(nextValues.commandPayload);
|
|
533
|
-
}}
|
|
534
|
-
onResizeStart={(event) => startResize('details-width', event, resizeDetailsPane)}
|
|
535
|
-
/>
|
|
536
|
-
</div>
|
|
537
|
-
|
|
538
|
-
<ResizeHandle
|
|
539
|
-
className="rz-column-resize-handle"
|
|
540
|
-
isDragging={activeResizeHandle === 'command-width'}
|
|
541
|
-
orientation="vertical"
|
|
542
|
-
label="Resize command dispatcher"
|
|
543
|
-
onPointerDown={(event) => startResize('command-width', event, resizeCommandPane)}
|
|
544
|
-
/>
|
|
545
|
-
|
|
546
|
-
<DispatchForm
|
|
547
|
-
commandType={commandType}
|
|
548
|
-
commandPayload={commandPayload}
|
|
549
|
-
flows={flows}
|
|
550
|
-
flowRuns={flowRuns}
|
|
551
|
-
hasRunningFlow={hasRunningFlow}
|
|
552
|
-
presets={presets}
|
|
553
|
-
canDispatch={canDispatch}
|
|
554
|
-
onRunFlow={runFlow}
|
|
555
|
-
onStopFlow={stopFlow}
|
|
556
|
-
onCommandTypeChange={setCommandType}
|
|
557
|
-
onCommandPayloadChange={setCommandPayload}
|
|
558
|
-
onApplyPreset={applyPreset}
|
|
559
|
-
onReset={resetForm}
|
|
560
|
-
onSubmit={handleDispatch}
|
|
561
|
-
/>
|
|
562
|
-
</section>
|
|
563
|
-
)}
|
|
564
|
-
</main>
|
|
565
|
-
</div>
|
|
327
|
+
)}
|
|
328
|
+
</Split.Pane>
|
|
329
|
+
<Split.Handle />
|
|
330
|
+
<Split.Pane defaultSize={36} minSize={25}>
|
|
331
|
+
{devtools}
|
|
332
|
+
</Split.Pane>
|
|
333
|
+
</Split>
|
|
334
|
+
</PluginShell.Body>
|
|
335
|
+
</PluginShell>
|
|
566
336
|
);
|
|
567
337
|
};
|