@godscene/playground-electron 1.7.11

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 (98) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -0
  3. package/dist/es/DeviceInteractionLayer.mjs +383 -0
  4. package/dist/es/PlaygroundApp.css +207 -0
  5. package/dist/es/PlaygroundApp.mjs +776 -0
  6. package/dist/es/PlaygroundPreview.mjs +29 -0
  7. package/dist/es/PlaygroundThemeProvider.mjs +10 -0
  8. package/dist/es/PreviewRenderer.mjs +270 -0
  9. package/dist/es/ScrcpyPanel.mjs +390 -0
  10. package/dist/es/SessionSetupPanel.css +299 -0
  11. package/dist/es/SessionSetupPanel.mjs +169 -0
  12. package/dist/es/components/Header/index.css +19 -0
  13. package/dist/es/components/Header/index.mjs +37 -0
  14. package/dist/es/components/Nav/index.css +15 -0
  15. package/dist/es/components/Nav/index.mjs +93 -0
  16. package/dist/es/components/WinControlTool/index.css +5 -0
  17. package/dist/es/components/WinControlTool/index.mjs +76 -0
  18. package/dist/es/controller/ai-config.mjs +40 -0
  19. package/dist/es/controller/auto-create.mjs +19 -0
  20. package/dist/es/controller/selectors.mjs +78 -0
  21. package/dist/es/controller/single-flight.mjs +13 -0
  22. package/dist/es/controller/types.mjs +0 -0
  23. package/dist/es/controller/usePlaygroundController.mjs +400 -0
  24. package/dist/es/icons/dropdown-chevron.mjs +61 -0
  25. package/dist/es/icons/midscene-logo.mjs +247 -0
  26. package/dist/es/icons/server-offline-background.mjs +102 -0
  27. package/dist/es/icons/server-offline-foreground.mjs +200 -0
  28. package/dist/es/index.mjs +7 -0
  29. package/dist/es/manual-interaction.mjs +56 -0
  30. package/dist/es/panels/PlaygroundConversationPanel.css +20 -0
  31. package/dist/es/panels/PlaygroundConversationPanel.mjs +140 -0
  32. package/dist/es/runtime-info.mjs +128 -0
  33. package/dist/es/scrcpy-preview.mjs +30 -0
  34. package/dist/es/scrcpy-stream.mjs +53 -0
  35. package/dist/es/session-setup.mjs +13 -0
  36. package/dist/es/session-state.mjs +32 -0
  37. package/dist/es/useServerStatus.mjs +120 -0
  38. package/dist/lib/DeviceInteractionLayer.js +434 -0
  39. package/dist/lib/PlaygroundApp.css +207 -0
  40. package/dist/lib/PlaygroundApp.js +821 -0
  41. package/dist/lib/PlaygroundPreview.js +63 -0
  42. package/dist/lib/PlaygroundThemeProvider.js +44 -0
  43. package/dist/lib/PreviewRenderer.js +304 -0
  44. package/dist/lib/ScrcpyPanel.js +424 -0
  45. package/dist/lib/SessionSetupPanel.css +299 -0
  46. package/dist/lib/SessionSetupPanel.js +217 -0
  47. package/dist/lib/components/Header/index.css +19 -0
  48. package/dist/lib/components/Header/index.js +81 -0
  49. package/dist/lib/components/Nav/index.css +15 -0
  50. package/dist/lib/components/Nav/index.js +127 -0
  51. package/dist/lib/components/WinControlTool/index.css +5 -0
  52. package/dist/lib/components/WinControlTool/index.js +110 -0
  53. package/dist/lib/controller/ai-config.js +80 -0
  54. package/dist/lib/controller/auto-create.js +59 -0
  55. package/dist/lib/controller/selectors.js +115 -0
  56. package/dist/lib/controller/single-flight.js +47 -0
  57. package/dist/lib/controller/types.js +18 -0
  58. package/dist/lib/controller/usePlaygroundController.js +434 -0
  59. package/dist/lib/icons/dropdown-chevron.js +95 -0
  60. package/dist/lib/icons/midscene-logo.js +281 -0
  61. package/dist/lib/icons/server-offline-background.js +136 -0
  62. package/dist/lib/icons/server-offline-foreground.js +234 -0
  63. package/dist/lib/index.js +56 -0
  64. package/dist/lib/manual-interaction.js +90 -0
  65. package/dist/lib/panels/PlaygroundConversationPanel.css +20 -0
  66. package/dist/lib/panels/PlaygroundConversationPanel.js +174 -0
  67. package/dist/lib/runtime-info.js +174 -0
  68. package/dist/lib/scrcpy-preview.js +79 -0
  69. package/dist/lib/scrcpy-stream.js +87 -0
  70. package/dist/lib/session-setup.js +47 -0
  71. package/dist/lib/session-state.js +69 -0
  72. package/dist/lib/useServerStatus.js +154 -0
  73. package/dist/types/DeviceInteractionLayer.d.ts +50 -0
  74. package/dist/types/PlaygroundApp.d.ts +14 -0
  75. package/dist/types/PlaygroundPreview.d.ts +22 -0
  76. package/dist/types/PlaygroundThemeProvider.d.ts +2 -0
  77. package/dist/types/PreviewRenderer.d.ts +27 -0
  78. package/dist/types/ScrcpyPanel.d.ts +21 -0
  79. package/dist/types/SessionSetupPanel.d.ts +16 -0
  80. package/dist/types/components/Header/index.d.ts +3 -0
  81. package/dist/types/components/Nav/index.d.ts +3 -0
  82. package/dist/types/components/WinControlTool/index.d.ts +3 -0
  83. package/dist/types/controller/ai-config.d.ts +5 -0
  84. package/dist/types/controller/auto-create.d.ts +15 -0
  85. package/dist/types/controller/selectors.d.ts +5 -0
  86. package/dist/types/controller/single-flight.d.ts +3 -0
  87. package/dist/types/controller/types.d.ts +36 -0
  88. package/dist/types/controller/usePlaygroundController.d.ts +16 -0
  89. package/dist/types/index.d.ts +13 -0
  90. package/dist/types/manual-interaction.d.ts +21 -0
  91. package/dist/types/panels/PlaygroundConversationPanel.d.ts +25 -0
  92. package/dist/types/runtime-info.d.ts +22 -0
  93. package/dist/types/scrcpy-preview.d.ts +11 -0
  94. package/dist/types/scrcpy-stream.d.ts +16 -0
  95. package/dist/types/session-setup.d.ts +2 -0
  96. package/dist/types/session-state.d.ts +9 -0
  97. package/dist/types/useServerStatus.d.ts +12 -0
  98. package/package.json +69 -0
@@ -0,0 +1,29 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { PreviewRenderer } from "./PreviewRenderer.mjs";
3
+ function _define_property(obj, key, value) {
4
+ if (key in obj) Object.defineProperty(obj, key, {
5
+ value: value,
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true
9
+ });
10
+ else obj[key] = value;
11
+ return obj;
12
+ }
13
+ function _object_spread(target) {
14
+ for(var i = 1; i < arguments.length; i++){
15
+ var source = null != arguments[i] ? arguments[i] : {};
16
+ var ownKeys = Object.keys(source);
17
+ if ("function" == typeof Object.getOwnPropertySymbols) ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
18
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
19
+ }));
20
+ ownKeys.forEach(function(key) {
21
+ _define_property(target, key, source[key]);
22
+ });
23
+ }
24
+ return target;
25
+ }
26
+ function PlaygroundPreview(props) {
27
+ return /*#__PURE__*/ jsx(PreviewRenderer, _object_spread({}, props));
28
+ }
29
+ export { PlaygroundPreview };
@@ -0,0 +1,10 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { globalThemeConfig } from "@godscene/visualizer";
3
+ import { ConfigProvider } from "antd";
4
+ function PlaygroundThemeProvider({ children }) {
5
+ return /*#__PURE__*/ jsx(ConfigProvider, {
6
+ theme: globalThemeConfig(),
7
+ children: children
8
+ });
9
+ }
10
+ export { PlaygroundThemeProvider };
@@ -0,0 +1,270 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { ScreenshotViewer } from "@godscene/visualizer";
3
+ import { WebCodecsVideoDecoder } from "@yume-chan/scrcpy-decoder-webcodecs";
4
+ import { Alert, Popover, message } from "antd";
5
+ import { useCallback, useEffect, useRef, useState } from "react";
6
+ import { DeviceInteractionLayer } from "./DeviceInteractionLayer.mjs";
7
+ import { ScrcpyPanel } from "./ScrcpyPanel.mjs";
8
+ import { buildManualDragInteractPayload } from "./manual-interaction.mjs";
9
+ import { resolvePreviewConnectionInfo } from "./runtime-info.mjs";
10
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
11
+ try {
12
+ var info = gen[key](arg);
13
+ var value = info.value;
14
+ } catch (error) {
15
+ reject(error);
16
+ return;
17
+ }
18
+ if (info.done) resolve(value);
19
+ else Promise.resolve(value).then(_next, _throw);
20
+ }
21
+ function _async_to_generator(fn) {
22
+ return function() {
23
+ var self = this, args = arguments;
24
+ return new Promise(function(resolve, reject) {
25
+ var gen = fn.apply(self, args);
26
+ function _next(value) {
27
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
28
+ }
29
+ function _throw(err) {
30
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
31
+ }
32
+ _next(void 0);
33
+ });
34
+ };
35
+ }
36
+ function isNonLocalhostHttp() {
37
+ try {
38
+ const { protocol, hostname } = window.location;
39
+ if ('http:' !== protocol) return false;
40
+ return 'localhost' !== hostname && '127.0.0.1' !== hostname && '::1' !== hostname;
41
+ } catch (unused) {
42
+ return false;
43
+ }
44
+ }
45
+ function PreviewRenderer({ connectingOverlay, onScrcpyStatusChange, renderErrorOverlay, scrcpyViewportStyle, screenshotViewerMode, playgroundSDK, runtimeInfo, serverUrl, serverOnline, isUserOperating, manualControlEnabled = false, manualDragActionType = 'Swipe', manualKeyboardEnabled = false }) {
46
+ const previewConnection = resolvePreviewConnectionInfo(runtimeInfo, serverUrl);
47
+ const [deviceSize, setDeviceSize] = useState(null);
48
+ const manualControlQueueRef = useRef(Promise.resolve());
49
+ const enqueueManualControl = useCallback((task)=>{
50
+ const nextTask = manualControlQueueRef.current.then(task, task);
51
+ manualControlQueueRef.current = nextTask.catch(()=>void 0);
52
+ return nextTask;
53
+ }, []);
54
+ useEffect(()=>{
55
+ if (!manualControlEnabled || !serverOnline) return void setDeviceSize(null);
56
+ let cancelled = false;
57
+ const fetchSize = ()=>_async_to_generator(function*() {
58
+ var _result_size;
59
+ let result;
60
+ try {
61
+ result = yield playgroundSDK.getInterfaceInfo();
62
+ } catch (unused) {
63
+ return;
64
+ }
65
+ if (cancelled) return;
66
+ if ((null == result ? void 0 : null == (_result_size = result.size) ? void 0 : _result_size.width) && result.size.height) {
67
+ const { size } = result;
68
+ setDeviceSize((current)=>{
69
+ if (current && current.width === size.width && current.height === size.height) return current;
70
+ return {
71
+ width: size.width,
72
+ height: size.height
73
+ };
74
+ });
75
+ }
76
+ })();
77
+ fetchSize();
78
+ const timer = setInterval(fetchSize, 5000);
79
+ return ()=>{
80
+ cancelled = true;
81
+ clearInterval(timer);
82
+ };
83
+ }, [
84
+ manualControlEnabled,
85
+ playgroundSDK,
86
+ serverOnline
87
+ ]);
88
+ const showManualControlError = useCallback((fallback, error)=>{
89
+ message.open({
90
+ type: 'error',
91
+ content: error || fallback,
92
+ key: 'manual-control-error'
93
+ });
94
+ }, []);
95
+ const handleTap = useCallback((point)=>_async_to_generator(function*() {
96
+ const res = yield enqueueManualControl(()=>playgroundSDK.interact({
97
+ actionType: 'Tap',
98
+ x: point.x,
99
+ y: point.y
100
+ }));
101
+ if (!res.ok) showManualControlError('Tap failed', res.error);
102
+ })(), [
103
+ enqueueManualControl,
104
+ playgroundSDK,
105
+ showManualControlError
106
+ ]);
107
+ const handleSwipe = useCallback((start, end, duration)=>_async_to_generator(function*() {
108
+ const res = yield enqueueManualControl(()=>playgroundSDK.interact(buildManualDragInteractPayload(manualDragActionType, start, end, duration)));
109
+ if (!res.ok) showManualControlError(`${manualDragActionType} failed`, res.error);
110
+ })(), [
111
+ enqueueManualControl,
112
+ manualDragActionType,
113
+ playgroundSDK,
114
+ showManualControlError
115
+ ]);
116
+ const handleTextInput = useCallback((text)=>_async_to_generator(function*() {
117
+ if (!text) return;
118
+ const res = yield enqueueManualControl(()=>playgroundSDK.interact({
119
+ actionType: 'Input',
120
+ value: text,
121
+ mode: 'typeOnly'
122
+ }));
123
+ if (!res.ok) showManualControlError('Input failed', res.error);
124
+ })(), [
125
+ enqueueManualControl,
126
+ playgroundSDK,
127
+ showManualControlError
128
+ ]);
129
+ const handleKeyboardPress = useCallback((keyName)=>_async_to_generator(function*() {
130
+ if (!keyName) return;
131
+ const res = yield enqueueManualControl(()=>playgroundSDK.interact({
132
+ actionType: 'KeyboardPress',
133
+ keyName
134
+ }));
135
+ if (!res.ok) showManualControlError('Keyboard press failed', res.error);
136
+ })(), [
137
+ enqueueManualControl,
138
+ playgroundSDK,
139
+ showManualControlError
140
+ ]);
141
+ const scrcpyAvailable = 'scrcpy' === previewConnection.type && WebCodecsVideoDecoder.isSupported;
142
+ const useScreenshot = 'screenshot' === previewConnection.type || 'scrcpy' === previewConnection.type && !scrcpyAvailable;
143
+ const showInsecureContextHint = 'scrcpy' === previewConnection.type && !WebCodecsVideoDecoder.isSupported && isNonLocalhostHttp();
144
+ return /*#__PURE__*/ jsxs("div", {
145
+ style: {
146
+ flex: 1,
147
+ minHeight: 0,
148
+ height: '100%',
149
+ position: 'relative'
150
+ },
151
+ children: [
152
+ showInsecureContextHint && /*#__PURE__*/ jsx(Popover, {
153
+ content: /*#__PURE__*/ jsxs("div", {
154
+ style: {
155
+ maxWidth: 360
156
+ },
157
+ children: [
158
+ /*#__PURE__*/ jsx("p", {
159
+ style: {
160
+ margin: '0 0 8px'
161
+ },
162
+ children: "Live scrcpy streaming is unavailable because WebCodecs API is disabled in non-secure (HTTP) contexts with non-localhost addresses."
163
+ }),
164
+ /*#__PURE__*/ jsx("p", {
165
+ style: {
166
+ margin: '0 0 8px'
167
+ },
168
+ children: "Currently using screenshot polling as fallback. To enable scrcpy streaming:"
169
+ }),
170
+ /*#__PURE__*/ jsxs("ol", {
171
+ style: {
172
+ margin: 0,
173
+ paddingLeft: 18
174
+ },
175
+ children: [
176
+ /*#__PURE__*/ jsxs("li", {
177
+ children: [
178
+ "Open",
179
+ ' ',
180
+ /*#__PURE__*/ jsx("code", {
181
+ children: "chrome://flags/#unsafely-treat-insecure-origin-as-secure"
182
+ })
183
+ ]
184
+ }),
185
+ /*#__PURE__*/ jsxs("li", {
186
+ children: [
187
+ "Add ",
188
+ /*#__PURE__*/ jsx("code", {
189
+ children: window.location.origin
190
+ })
191
+ ]
192
+ }),
193
+ /*#__PURE__*/ jsxs("li", {
194
+ children: [
195
+ "Set to ",
196
+ /*#__PURE__*/ jsx("b", {
197
+ children: "Enabled"
198
+ }),
199
+ " and relaunch Chrome"
200
+ ]
201
+ })
202
+ ]
203
+ })
204
+ ]
205
+ }),
206
+ title: "Screenshot polling mode",
207
+ trigger: "click",
208
+ placement: "bottomRight",
209
+ children: /*#__PURE__*/ jsx("button", {
210
+ type: "button",
211
+ style: {
212
+ position: 'absolute',
213
+ top: 8,
214
+ right: 8,
215
+ zIndex: 10,
216
+ background: '#faad14',
217
+ border: 'none',
218
+ borderRadius: '50%',
219
+ width: 28,
220
+ height: 28,
221
+ display: 'flex',
222
+ alignItems: 'center',
223
+ justifyContent: 'center',
224
+ cursor: 'pointer',
225
+ boxShadow: '0 2px 6px rgba(0,0,0,0.2)'
226
+ },
227
+ children: /*#__PURE__*/ jsx("span", {
228
+ style: {
229
+ color: '#fff',
230
+ fontSize: 14,
231
+ fontWeight: 'bold',
232
+ lineHeight: 1
233
+ },
234
+ children: "!"
235
+ })
236
+ })
237
+ }),
238
+ 'none' === previewConnection.type ? /*#__PURE__*/ jsx(Alert, {
239
+ type: "warning",
240
+ showIcon: true,
241
+ message: "Preview unavailable",
242
+ description: "This session did not expose a preview capability in runtime metadata."
243
+ }) : scrcpyAvailable ? /*#__PURE__*/ jsx(ScrcpyPanel, {
244
+ connectingOverlay: connectingOverlay,
245
+ deviceId: previewConnection.deviceId,
246
+ onStatusChange: onScrcpyStatusChange,
247
+ renderErrorOverlay: renderErrorOverlay,
248
+ serverUrl: previewConnection.scrcpyUrl,
249
+ viewportStyle: scrcpyViewportStyle
250
+ }) : /*#__PURE__*/ jsx(ScreenshotViewer, {
251
+ getScreenshot: ()=>useScreenshot ? playgroundSDK.getScreenshot() : Promise.resolve(null),
252
+ getInterfaceInfo: ()=>playgroundSDK.getInterfaceInfo(),
253
+ serverOnline: serverOnline,
254
+ isUserOperating: isUserOperating,
255
+ mjpegUrl: previewConnection.mjpegUrl,
256
+ mode: screenshotViewerMode
257
+ }),
258
+ /*#__PURE__*/ jsx(DeviceInteractionLayer, {
259
+ enabled: manualControlEnabled && serverOnline && 'none' !== previewConnection.type,
260
+ deviceSize: deviceSize,
261
+ onTap: handleTap,
262
+ onSwipe: handleSwipe,
263
+ keyboardEnabled: manualKeyboardEnabled,
264
+ onTextInput: handleTextInput,
265
+ onKeyboardPress: handleKeyboardPress
266
+ })
267
+ ]
268
+ });
269
+ }
270
+ export { PreviewRenderer };