@rozenite/vite-plugin 1.9.0 → 1.10.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.
Files changed (56) hide show
  1. package/dist/client-plugin.d.ts.map +1 -1
  2. package/dist/dev-config-module.d.ts +6 -0
  3. package/dist/dev-config-module.d.ts.map +1 -0
  4. package/dist/dev-host/assets/index-PNYu6V-J.css +1 -0
  5. package/dist/dev-host/assets/index-kRQeUY6W.js +11 -0
  6. package/{src/dev-host/dev-host.html → dist/dev-host/index.html} +2 -0
  7. package/dist/dev-host/manifest.json +11 -0
  8. package/dist/index.cjs +112 -10
  9. package/dist/index.js +112 -10
  10. package/dist/load-config.d.ts +39 -0
  11. package/dist/load-config.d.ts.map +1 -1
  12. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  13. package/package.json +8 -8
  14. package/dist/dev-host/App.d.ts +0 -3
  15. package/dist/dev-host/App.d.ts.map +0 -1
  16. package/dist/dev-host/components/DispatchForm.d.ts +0 -13
  17. package/dist/dev-host/components/DispatchForm.d.ts.map +0 -1
  18. package/dist/dev-host/components/MessageDetailsPane.d.ts +0 -18
  19. package/dist/dev-host/components/MessageDetailsPane.d.ts.map +0 -1
  20. package/dist/dev-host/components/MessageLogPane.d.ts +0 -10
  21. package/dist/dev-host/components/MessageLogPane.d.ts.map +0 -1
  22. package/dist/dev-host/components/MessagePayloadDetail.d.ts +0 -6
  23. package/dist/dev-host/components/MessagePayloadDetail.d.ts.map +0 -1
  24. package/dist/dev-host/components/PanelTabs.d.ts +0 -9
  25. package/dist/dev-host/components/PanelTabs.d.ts.map +0 -1
  26. package/dist/dev-host/components/ResizeHandle.d.ts +0 -12
  27. package/dist/dev-host/components/ResizeHandle.d.ts.map +0 -1
  28. package/dist/dev-host/components/icons.d.ts +0 -3
  29. package/dist/dev-host/components/icons.d.ts.map +0 -1
  30. package/dist/dev-host/components/ui/ScrollArea.d.ts +0 -6
  31. package/dist/dev-host/components/ui/ScrollArea.d.ts.map +0 -1
  32. package/dist/dev-host/components/ui/Tabs.d.ts +0 -5
  33. package/dist/dev-host/components/ui/Tabs.d.ts.map +0 -1
  34. package/dist/dev-host/constants.d.ts +0 -28
  35. package/dist/dev-host/constants.d.ts.map +0 -1
  36. package/dist/dev-host/index.d.ts +0 -1
  37. package/dist/dev-host/index.d.ts.map +0 -1
  38. package/dist/dev-host/types.d.ts +0 -29
  39. package/dist/dev-host/types.d.ts.map +0 -1
  40. package/dist/dev-host/utils.d.ts +0 -13
  41. package/dist/dev-host/utils.d.ts.map +0 -1
  42. package/src/dev-host/App.tsx +0 -403
  43. package/src/dev-host/components/DispatchForm.tsx +0 -87
  44. package/src/dev-host/components/MessageDetailsPane.tsx +0 -108
  45. package/src/dev-host/components/MessageLogPane.tsx +0 -84
  46. package/src/dev-host/components/MessagePayloadDetail.tsx +0 -32
  47. package/src/dev-host/components/PanelTabs.tsx +0 -22
  48. package/src/dev-host/components/ResizeHandle.tsx +0 -33
  49. package/src/dev-host/components/icons.tsx +0 -27
  50. package/src/dev-host/components/ui/ScrollArea.tsx +0 -46
  51. package/src/dev-host/components/ui/Tabs.tsx +0 -33
  52. package/src/dev-host/constants.ts +0 -29
  53. package/src/dev-host/index.tsx +0 -19
  54. package/src/dev-host/styles.css +0 -631
  55. package/src/dev-host/types.ts +0 -33
  56. package/src/dev-host/utils.ts +0 -96
@@ -1,10 +0,0 @@
1
- import { MessageEntry } from '../types.js';
2
- type MessageLogPaneProps = {
3
- messages: MessageEntry[];
4
- selectedMessageId: string | null;
5
- onSelectMessage: (messageId: string) => void;
6
- onClearMessages: () => void;
7
- };
8
- export declare const MessageLogPane: ({ messages, selectedMessageId, onSelectMessage, onClearMessages, }: MessageLogPaneProps) => import("react/jsx-runtime").JSX.Element;
9
- export {};
10
- //# sourceMappingURL=MessageLogPane.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MessageLogPane.d.ts","sourceRoot":"","sources":["../../../src/dev-host/components/MessageLogPane.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,oEAK5B,mBAAmB,4CAkErB,CAAC"}
@@ -1,6 +0,0 @@
1
- type MessagePayloadDetailProps = {
2
- payload: unknown;
3
- };
4
- export declare const MessagePayloadDetail: ({ payload }: MessagePayloadDetailProps) => import("react/jsx-runtime").JSX.Element;
5
- export {};
6
- //# sourceMappingURL=MessagePayloadDetail.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MessagePayloadDetail.d.ts","sourceRoot":"","sources":["../../../src/dev-host/components/MessagePayloadDetail.tsx"],"names":[],"mappings":"AAIA,KAAK,yBAAyB,GAAG;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,aAAa,yBAAyB,4CAuB1E,CAAC"}
@@ -1,9 +0,0 @@
1
- import { DevHostPanelEntry } from '../types.js';
2
- type PanelTabsProps = {
3
- panels: DevHostPanelEntry[];
4
- activeSource: string;
5
- onValueChange: (value: string) => void;
6
- };
7
- export declare const PanelTabs: ({ panels, activeSource, onValueChange }: PanelTabsProps) => import("react/jsx-runtime").JSX.Element;
8
- export {};
9
- //# sourceMappingURL=PanelTabs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PanelTabs.d.ts","sourceRoot":"","sources":["../../../src/dev-host/components/PanelTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,yCAAyC,cAAc,4CAYhF,CAAC"}
@@ -1,12 +0,0 @@
1
- import { PointerEvent as ReactPointerEvent } from 'react';
2
- type ResizeHandleProps = {
3
- className?: string;
4
- isDragging: boolean;
5
- isHidden?: boolean;
6
- orientation: 'horizontal' | 'vertical';
7
- label: string;
8
- onPointerDown: (event: ReactPointerEvent<HTMLDivElement>) => void;
9
- };
10
- export declare const ResizeHandle: ({ className, isDragging, isHidden, orientation, label, onPointerDown, }: ResizeHandleProps) => import("react/jsx-runtime").JSX.Element;
11
- export {};
12
- //# sourceMappingURL=ResizeHandle.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ResizeHandle.d.ts","sourceRoot":"","sources":["../../../src/dev-host/components/ResizeHandle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,IAAI,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/D,KAAK,iBAAiB,GAAG;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,YAAY,GAAG,UAAU,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CACnE,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,yEAO1B,iBAAiB,4CAanB,CAAC"}
@@ -1,3 +0,0 @@
1
- export declare const ClearIcon: () => import("react/jsx-runtime").JSX.Element;
2
- export declare const SendIcon: () => import("react/jsx-runtime").JSX.Element;
3
- //# sourceMappingURL=icons.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/dev-host/components/icons.tsx"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,+CAYrB,CAAC;AAEF,eAAO,MAAM,QAAQ,+CAYpB,CAAC"}
@@ -1,6 +0,0 @@
1
- import { ReactNode } from 'react';
2
- import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
3
- export declare const ScrollArea: import('react').ForwardRefExoticComponent<Omit<ScrollAreaPrimitive.ScrollAreaProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & {
4
- children: ReactNode;
5
- } & import('react').RefAttributes<HTMLDivElement>>;
6
- //# sourceMappingURL=ScrollArea.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../../../../src/dev-host/components/ui/ScrollArea.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,mBAAmB,MAAM,6BAA6B,CAAC;AAwBnE,eAAO,MAAM,UAAU;cApBX,SAAS;kDAiCnB,CAAC"}
@@ -1,5 +0,0 @@
1
- import * as TabsPrimitive from '@radix-ui/react-tabs';
2
- export declare const Tabs: import('react').ForwardRefExoticComponent<TabsPrimitive.TabsProps & import('react').RefAttributes<HTMLDivElement>>;
3
- export declare const TabsList: import('react').ForwardRefExoticComponent<Omit<TabsPrimitive.TabsListProps & import('react').RefAttributes<HTMLDivElement>, "ref"> & import('react').RefAttributes<HTMLDivElement>>;
4
- export declare const TabsTrigger: import('react').ForwardRefExoticComponent<Omit<TabsPrimitive.TabsTriggerProps & import('react').RefAttributes<HTMLButtonElement>, "ref"> & import('react').RefAttributes<HTMLButtonElement>>;
5
- //# sourceMappingURL=Tabs.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/dev-host/components/ui/Tabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAGtD,eAAO,MAAM,IAAI,oHAAqB,CAAC;AAEvC,eAAO,MAAM,QAAQ,qLAKnB,CAAC;AAIH,eAAO,MAAM,WAAW,8LAWtB,CAAC"}
@@ -1,28 +0,0 @@
1
- export declare const DEV_HOST_STATE_ELEMENT_ID = "__rozenite-dev-host__";
2
- export declare const DEFAULT_DEVTOOLS_HEIGHT = 288;
3
- export declare const MIN_DEVTOOLS_HEIGHT = 180;
4
- export declare const MIN_IFRAME_HEIGHT = 220;
5
- export declare const DETAILS_PANEL_WIDTH = 360;
6
- export declare const MIN_DETAILS_WIDTH = 280;
7
- export declare const DEFAULT_COMMAND_WIDTH = 320;
8
- export declare const MIN_COMMAND_WIDTH = 260;
9
- export declare const SPLITTER_SIZE = 6;
10
- export declare const jsonTreeTheme: {
11
- base00: string;
12
- base01: string;
13
- base02: string;
14
- base03: string;
15
- base04: string;
16
- base05: string;
17
- base06: string;
18
- base07: string;
19
- base08: string;
20
- base09: string;
21
- base0A: string;
22
- base0B: string;
23
- base0C: string;
24
- base0D: string;
25
- base0E: string;
26
- base0F: string;
27
- };
28
- //# sourceMappingURL=constants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/dev-host/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;CAiBzB,CAAC"}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dev-host/index.tsx"],"names":[],"mappings":"AAGA,OAAO,cAAc,CAAC"}
@@ -1,29 +0,0 @@
1
- export type DevHostPanelEntry = {
2
- label: string;
3
- source: string;
4
- };
5
- export type DevHostState = {
6
- packageName: string;
7
- packageDescription: string;
8
- panels: DevHostPanelEntry[];
9
- };
10
- export type MessageEntry = {
11
- id: string;
12
- direction: 'in' | 'out';
13
- date: string;
14
- type: string;
15
- payload: unknown;
16
- };
17
- export type PluginMessage = {
18
- pluginId: string;
19
- type: string;
20
- payload: unknown;
21
- };
22
- export type ResizeHandleId = 'devtools-height' | 'command-width' | 'details-width';
23
- export type ResizeSession = {
24
- handleId: ResizeHandleId;
25
- pointerId: number;
26
- element: HTMLElement;
27
- onMove: (event: PointerEvent) => void;
28
- };
29
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dev-host/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,IAAI,GAAG,KAAK,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEnF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CACvC,CAAC"}
@@ -1,13 +0,0 @@
1
- import { DevHostPanelEntry, DevHostState, MessageEntry, PluginMessage } from './types.js';
2
- export declare const cn: (...parts: Array<string | false | null | undefined>) => string;
3
- export declare const formatPayloadPreview: (payload: unknown) => string;
4
- export declare const isJsonTreeData: (value: unknown) => value is Record<string, unknown> | unknown[];
5
- export declare const formatMessageDate: (date: string) => string;
6
- export declare const formatMessageTableDate: (date: string) => string;
7
- export declare const formatPayloadForCommandInput: (payload: unknown) => string;
8
- export declare const isPluginMessage: (value: unknown) => value is PluginMessage;
9
- export declare const getInitialPanel: (panels: DevHostPanelEntry[]) => DevHostPanelEntry;
10
- export declare const createMessageEntry: (input: Omit<MessageEntry, "id" | "date">) => MessageEntry;
11
- export declare const clamp: (value: number, min: number, max: number) => number;
12
- export declare const readDevHostState: () => DevHostState;
13
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/dev-host/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/F,eAAO,MAAM,EAAE,GAAI,GAAG,OAAO,KAAK,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC,WAEpE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,SAAS,OAAO,WAcpD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAEzF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,WAE7C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,MAAM,MAAM,WASlD,CAAC;AAEF,eAAO,MAAM,4BAA4B,GAAI,SAAS,OAAO,WAM5D,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,aAQzD,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ,iBAAiB,EAAE,sBAW1D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,OAAO,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,MAAM,CAAC,KACvC,YAMF,CAAC;AAEF,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,WAE5D,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,YAQnC,CAAC"}
@@ -1,403 +0,0 @@
1
- import {
2
- useEffect,
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
- SPLITTER_SIZE,
18
- } from './constants.js';
19
- import type {
20
- DevHostPanelEntry,
21
- DevHostState,
22
- MessageEntry,
23
- ResizeHandleId,
24
- ResizeSession,
25
- } from './types.js';
26
- import { clamp, createMessageEntry, getInitialPanel, isPluginMessage } from './utils.js';
27
- import { DispatchForm } from './components/DispatchForm.js';
28
- import {
29
- MessageDetailsPane,
30
- getDispatcherValuesFromMessage,
31
- } from './components/MessageDetailsPane.js';
32
- import { MessageLogPane } from './components/MessageLogPane.js';
33
- import { PanelTabs } from './components/PanelTabs.js';
34
- import { ResizeHandle } from './components/ResizeHandle.js';
35
-
36
- type CSSVariables = CSSProperties & Record<`--${string}`, string>;
37
-
38
- const getViewportMatch = () => {
39
- return window.matchMedia('(max-width: 960px)').matches;
40
- };
41
-
42
- export const App = ({ packageName, packageDescription, panels }: DevHostState) => {
43
- const [activePanel, setActivePanel] = useState<DevHostPanelEntry | null>(() => {
44
- return getInitialPanel(panels);
45
- });
46
- const [commandType, setCommandType] = useState('');
47
- const [commandPayload, setCommandPayload] = useState('');
48
- const [messages, setMessages] = useState<MessageEntry[]>([]);
49
- const [selectedMessageId, setSelectedMessageId] = useState<string | null>(null);
50
- const [isDetailsOpen, setIsDetailsOpen] = useState(false);
51
- const [devToolsHeight, setDevToolsHeight] = useState(DEFAULT_DEVTOOLS_HEIGHT);
52
- const [commandWidth, setCommandWidth] = useState(DEFAULT_COMMAND_WIDTH);
53
- const [detailsWidth, setDetailsWidth] = useState(DETAILS_PANEL_WIDTH);
54
- const [activeResizeHandle, setActiveResizeHandle] = useState<ResizeHandleId | null>(null);
55
- const [isNarrowViewport, setIsNarrowViewport] = useState(getViewportMatch);
56
- const workspaceRef = useRef<HTMLElement | null>(null);
57
- const logWorkspaceRef = useRef<HTMLDivElement | null>(null);
58
- const devtoolsRef = useRef<HTMLElement | null>(null);
59
- const resizeSessionRef = useRef<ResizeSession | null>(null);
60
- const iframeRef = useRef<HTMLIFrameElement | null>(null);
61
-
62
- const activeSource = activePanel?.source ?? '';
63
- const activeLabel = activePanel?.label ?? '';
64
- const emptyState = panels.length === 0;
65
- const selectedMessage = messages.find((message) => message.id === selectedMessageId) ?? null;
66
- const trimmedCommandType = commandType.trim();
67
- const trimmedCommandPayload = commandPayload.trim();
68
- const hasCommandType = trimmedCommandType.length > 0;
69
- const hasValidCommandPayload = (() => {
70
- if (!trimmedCommandPayload) {
71
- return false;
72
- }
73
-
74
- try {
75
- JSON.parse(commandPayload);
76
- return true;
77
- } catch {
78
- return false;
79
- }
80
- })();
81
- const canDispatch = hasCommandType && hasValidCommandPayload;
82
- const panelDescription = packageDescription.trim();
83
-
84
- useEffect(() => {
85
- document.title = `${packageName} Dev Host`;
86
- }, [packageName]);
87
-
88
- useEffect(() => {
89
- const mediaQuery = window.matchMedia('(max-width: 960px)');
90
-
91
- const handleChange = (event: MediaQueryListEvent) => {
92
- setIsNarrowViewport(event.matches);
93
- };
94
-
95
- setIsNarrowViewport(mediaQuery.matches);
96
- mediaQuery.addEventListener('change', handleChange);
97
-
98
- return () => {
99
- mediaQuery.removeEventListener('change', handleChange);
100
- };
101
- }, []);
102
-
103
- const selectPanel = (value: string) => {
104
- const nextPanel = panels.find((panel) => panel.source === value);
105
- if (!nextPanel) {
106
- return;
107
- }
108
-
109
- setActivePanel(nextPanel);
110
- const nextUrl = new URL(window.location.href);
111
- nextUrl.searchParams.set('panel', nextPanel.label);
112
- window.history.replaceState(null, '', nextUrl);
113
- };
114
-
115
- const appendMessage = (input: Omit<MessageEntry, 'id' | 'date'>) => {
116
- const nextEntry = createMessageEntry(input);
117
-
118
- setMessages((current) => [nextEntry, ...current]);
119
- setSelectedMessageId(nextEntry.id);
120
- setIsDetailsOpen(true);
121
- };
122
-
123
- useEffect(() => {
124
- const handlePointerMove = (event: PointerEvent) => {
125
- resizeSessionRef.current?.onMove(event);
126
- };
127
-
128
- const stopDragging = () => {
129
- const session = resizeSessionRef.current;
130
- if (!session) {
131
- return;
132
- }
133
-
134
- if (session.element.hasPointerCapture(session.pointerId)) {
135
- session.element.releasePointerCapture(session.pointerId);
136
- }
137
-
138
- resizeSessionRef.current = null;
139
- setActiveResizeHandle(null);
140
- };
141
-
142
- window.addEventListener('pointermove', handlePointerMove);
143
- window.addEventListener('pointerup', stopDragging);
144
- window.addEventListener('pointercancel', stopDragging);
145
-
146
- return () => {
147
- window.removeEventListener('pointermove', handlePointerMove);
148
- window.removeEventListener('pointerup', stopDragging);
149
- window.removeEventListener('pointercancel', stopDragging);
150
- };
151
- }, []);
152
-
153
- const startResize = (
154
- handleId: ResizeHandleId,
155
- event: ReactPointerEvent<HTMLDivElement>,
156
- onMove: (event: PointerEvent) => void,
157
- ) => {
158
- event.preventDefault();
159
- event.currentTarget.setPointerCapture(event.pointerId);
160
- resizeSessionRef.current = {
161
- handleId,
162
- pointerId: event.pointerId,
163
- element: event.currentTarget,
164
- onMove,
165
- };
166
- setActiveResizeHandle(handleId);
167
- };
168
-
169
- useEffect(() => {
170
- const handleMessage = (event: MessageEvent) => {
171
- if (event.source !== iframeRef.current?.contentWindow) {
172
- return;
173
- }
174
-
175
- if (
176
- typeof event.data !== 'object' ||
177
- event.data === null ||
178
- !('type' in event.data) ||
179
- event.data.type !== 'rozenite-message' ||
180
- !('payload' in event.data)
181
- ) {
182
- return;
183
- }
184
-
185
- const payload = event.data.payload;
186
-
187
- if (!isPluginMessage(payload)) {
188
- return;
189
- }
190
-
191
- appendMessage({
192
- direction: 'out',
193
- type: payload.type,
194
- payload: payload.payload,
195
- });
196
- };
197
-
198
- window.addEventListener('message', handleMessage);
199
-
200
- return () => {
201
- window.removeEventListener('message', handleMessage);
202
- };
203
- }, []);
204
-
205
- const resetForm = () => {
206
- setCommandType('');
207
- setCommandPayload('');
208
- };
209
-
210
- const clearMessages = () => {
211
- setMessages([]);
212
- setSelectedMessageId(null);
213
- setIsDetailsOpen(false);
214
- };
215
-
216
- const resizeDevtoolsHeight = (event: PointerEvent) => {
217
- const workspace = workspaceRef.current;
218
- if (!workspace) {
219
- return;
220
- }
221
-
222
- const bounds = workspace.getBoundingClientRect();
223
- const nextHeight = bounds.bottom - event.clientY;
224
- const maxHeight = Math.max(MIN_DEVTOOLS_HEIGHT, bounds.height - MIN_IFRAME_HEIGHT - 12);
225
-
226
- setDevToolsHeight(clamp(nextHeight, MIN_DEVTOOLS_HEIGHT, maxHeight));
227
- };
228
-
229
- const resizeCommandPane = (event: PointerEvent) => {
230
- const devtools = devtoolsRef.current;
231
- if (!devtools) {
232
- return;
233
- }
234
-
235
- const bounds = devtools.getBoundingClientRect();
236
- const nextWidth = isNarrowViewport
237
- ? bounds.bottom - event.clientY
238
- : bounds.right - event.clientX;
239
- const maxWidth = Math.max(MIN_COMMAND_WIDTH, bounds.width - 280);
240
-
241
- setCommandWidth(clamp(nextWidth, MIN_COMMAND_WIDTH, maxWidth));
242
- };
243
-
244
- const resizeDetailsPane = (event: PointerEvent) => {
245
- const logWorkspace = logWorkspaceRef.current;
246
- if (!logWorkspace || !isDetailsOpen || !selectedMessage) {
247
- return;
248
- }
249
-
250
- const bounds = logWorkspace.getBoundingClientRect();
251
- const nextWidth = isNarrowViewport
252
- ? bounds.bottom - event.clientY
253
- : bounds.right - event.clientX;
254
- const maxWidth = Math.max(MIN_DETAILS_WIDTH, bounds.width - 280 - SPLITTER_SIZE);
255
-
256
- setDetailsWidth(clamp(nextWidth, MIN_DETAILS_WIDTH, maxWidth));
257
- };
258
-
259
- const handleDispatch = (event: FormEvent<HTMLFormElement>) => {
260
- event.preventDefault();
261
-
262
- if (!canDispatch) {
263
- return;
264
- }
265
-
266
- const type = trimmedCommandType;
267
-
268
- let payload: unknown;
269
-
270
- try {
271
- payload = JSON.parse(commandPayload);
272
- } catch (error) {
273
- window.alert(
274
- error instanceof Error
275
- ? `Payload must be valid JSON. ${error.message}`
276
- : 'Payload must be valid JSON.',
277
- );
278
- return;
279
- }
280
-
281
- iframeRef.current?.contentWindow?.postMessage(
282
- {
283
- pluginId: packageName,
284
- type,
285
- payload,
286
- },
287
- '*',
288
- );
289
-
290
- appendMessage({
291
- direction: 'in',
292
- type,
293
- payload,
294
- });
295
-
296
- resetForm();
297
- };
298
-
299
- return (
300
- <div className="rz-shell">
301
- <header className="rz-topbar">
302
- <div title={panelDescription || undefined}>
303
- <PanelTabs panels={panels} activeSource={activeSource} onValueChange={selectPanel} />
304
- </div>
305
- </header>
306
-
307
- <main
308
- ref={workspaceRef}
309
- className="rz-workspace"
310
- style={{ '--rz-devtools-height': `${devToolsHeight}px` } as CSSVariables}
311
- >
312
- <section className="rz-card">
313
- {emptyState ? (
314
- <div className="rz-empty-state">No panels were defined in rozenite.config.ts.</div>
315
- ) : (
316
- <iframe
317
- key={activeSource}
318
- ref={iframeRef}
319
- title={activeLabel || 'Rozenite panel preview'}
320
- src={activeSource}
321
- className="rz-iframe"
322
- data-resizing={activeResizeHandle === 'devtools-height'}
323
- />
324
- )}
325
- </section>
326
-
327
- <ResizeHandle
328
- className="rz-resize-handle"
329
- isDragging={activeResizeHandle === 'devtools-height'}
330
- orientation="horizontal"
331
- label="Resize DevTools"
332
- onPointerDown={(event) => startResize('devtools-height', event, resizeDevtoolsHeight)}
333
- />
334
-
335
- <section
336
- ref={devtoolsRef}
337
- className="rz-devtools"
338
- style={
339
- {
340
- '--rz-command-width': `${commandWidth}px`,
341
- '--rz-command-splitter-width': `${SPLITTER_SIZE}px`,
342
- } as CSSVariables
343
- }
344
- >
345
- <div
346
- ref={logWorkspaceRef}
347
- className="rz-log-workspace"
348
- style={
349
- {
350
- '--rz-details-width':
351
- isDetailsOpen && selectedMessage ? `${detailsWidth}px` : '0px',
352
- '--rz-details-splitter-width':
353
- isDetailsOpen && selectedMessage ? `${SPLITTER_SIZE}px` : '0px',
354
- } as CSSVariables
355
- }
356
- >
357
- <MessageLogPane
358
- messages={messages}
359
- selectedMessageId={selectedMessageId}
360
- onSelectMessage={(messageId) => {
361
- setSelectedMessageId(messageId);
362
- setIsDetailsOpen(true);
363
- }}
364
- onClearMessages={clearMessages}
365
- />
366
-
367
- <MessageDetailsPane
368
- selectedMessage={selectedMessage}
369
- isOpen={isDetailsOpen}
370
- isNarrowViewport={isNarrowViewport}
371
- activeResizeHandle={activeResizeHandle}
372
- onClose={() => setIsDetailsOpen(false)}
373
- onUseMessage={(message) => {
374
- const nextValues = getDispatcherValuesFromMessage(message);
375
- setCommandType(nextValues.commandType);
376
- setCommandPayload(nextValues.commandPayload);
377
- }}
378
- onResizeStart={(event) => startResize('details-width', event, resizeDetailsPane)}
379
- />
380
- </div>
381
-
382
- <ResizeHandle
383
- className="rz-column-resize-handle"
384
- isDragging={activeResizeHandle === 'command-width'}
385
- orientation={isNarrowViewport ? 'horizontal' : 'vertical'}
386
- label="Resize command dispatcher"
387
- onPointerDown={(event) => startResize('command-width', event, resizeCommandPane)}
388
- />
389
-
390
- <DispatchForm
391
- commandType={commandType}
392
- commandPayload={commandPayload}
393
- canDispatch={canDispatch}
394
- onCommandTypeChange={setCommandType}
395
- onCommandPayloadChange={setCommandPayload}
396
- onReset={resetForm}
397
- onSubmit={handleDispatch}
398
- />
399
- </section>
400
- </main>
401
- </div>
402
- );
403
- };
@@ -1,87 +0,0 @@
1
- import type { FormEvent } from 'react';
2
- import { ClearIcon, SendIcon } from './icons.js';
3
- import { ScrollArea } from './ui/ScrollArea.js';
4
-
5
- type DispatchFormProps = {
6
- commandType: string;
7
- commandPayload: string;
8
- canDispatch: boolean;
9
- onCommandTypeChange: (value: string) => void;
10
- onCommandPayloadChange: (value: string) => void;
11
- onReset: () => void;
12
- onSubmit: (event: FormEvent<HTMLFormElement>) => void;
13
- };
14
-
15
- export const DispatchForm = ({
16
- commandType,
17
- commandPayload,
18
- canDispatch,
19
- onCommandTypeChange,
20
- onCommandPayloadChange,
21
- onReset,
22
- onSubmit,
23
- }: DispatchFormProps) => {
24
- return (
25
- <div className="rz-pane">
26
- <div className="rz-sidebar">
27
- <div className="rz-sidebar-header">
28
- <div className="rz-sidebar-title">Dispatch Message</div>
29
- </div>
30
-
31
- <ScrollArea className="rz-sidebar-scroll">
32
- <form className="rz-command-form" onSubmit={onSubmit}>
33
- <div className="rz-field">
34
- <label className="rz-label" htmlFor="command-type">
35
- Command
36
- </label>
37
- <input
38
- id="command-type"
39
- className="rz-input"
40
- value={commandType}
41
- onChange={(event) => onCommandTypeChange(event.currentTarget.value)}
42
- placeholder="get-snapshot"
43
- spellCheck={false}
44
- />
45
- </div>
46
-
47
- <div className="rz-field">
48
- <label className="rz-label" htmlFor="command-payload">
49
- Payload
50
- </label>
51
- <textarea
52
- id="command-payload"
53
- className="rz-textarea"
54
- value={commandPayload}
55
- onChange={(event) => onCommandPayloadChange(event.currentTarget.value)}
56
- placeholder='{"example": true}'
57
- spellCheck={false}
58
- />
59
- </div>
60
-
61
- <div className="rz-button-row">
62
- <button
63
- type="button"
64
- className="rz-sidebar-close"
65
- aria-label="Reset dispatcher"
66
- title="Reset dispatcher"
67
- onClick={onReset}
68
- >
69
- <ClearIcon />
70
- </button>
71
-
72
- <button
73
- type="submit"
74
- className="rz-sidebar-close rz-sidebar-action-primary"
75
- aria-label="Dispatch message"
76
- title="Dispatch message"
77
- disabled={!canDispatch}
78
- >
79
- <SendIcon />
80
- </button>
81
- </div>
82
- </form>
83
- </ScrollArea>
84
- </div>
85
- </div>
86
- );
87
- };