@midscene/playground 1.8.0 → 1.8.1

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.
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.n = (module)=>{
5
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
6
+ __webpack_require__.d(getter, {
7
+ a: getter
8
+ });
9
+ return getter;
10
+ };
11
+ })();
12
+ (()=>{
13
+ __webpack_require__.d = (exports1, definition)=>{
14
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
+ enumerable: true,
16
+ get: definition[key]
17
+ });
18
+ };
19
+ })();
20
+ (()=>{
21
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
22
+ })();
23
+ (()=>{
24
+ __webpack_require__.r = (exports1)=>{
25
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
26
+ value: 'Module'
27
+ });
28
+ Object.defineProperty(exports1, '__esModule', {
29
+ value: true
30
+ });
31
+ };
32
+ })();
33
+ var __webpack_exports__ = {};
34
+ __webpack_require__.r(__webpack_exports__);
35
+ __webpack_require__.d(__webpack_exports__, {
36
+ MjpegStreamHandler: ()=>MjpegStreamHandler
37
+ });
38
+ const external_node_http_namespaceObject = require("node:http");
39
+ var external_node_http_default = /*#__PURE__*/ __webpack_require__.n(external_node_http_namespaceObject);
40
+ const logger_namespaceObject = require("@midscene/shared/logger");
41
+ const external_mjpeg_hub_js_namespaceObject = require("./mjpeg-hub.js");
42
+ function _define_property(obj, key, value) {
43
+ if (key in obj) Object.defineProperty(obj, key, {
44
+ value: value,
45
+ enumerable: true,
46
+ configurable: true,
47
+ writable: true
48
+ });
49
+ else obj[key] = value;
50
+ return obj;
51
+ }
52
+ const debugMjpeg = (0, logger_namespaceObject.getDebug)('playground:mjpeg', {
53
+ console: true
54
+ });
55
+ const NEGATIVE_CACHE_MS = 10000;
56
+ const NATIVE_PROBE_INTERVAL_MS = 3000;
57
+ const INTERFACE_MJPEG_INITIAL_FRAME_TIMEOUT_MS = 1500;
58
+ const INTERFACE_MJPEG_IDLE_STOP_MS = 2000;
59
+ const DEFAULT_FPS = 10;
60
+ const MAX_FPS = 30;
61
+ const MAX_ERROR_BACKOFF_MS = 3000;
62
+ const ERROR_LOG_THRESHOLD = 3;
63
+ class MjpegStreamHandler {
64
+ reset() {
65
+ this.nativeAvailable = null;
66
+ this.nativeFailedAt = null;
67
+ this.interfaceMjpegHub.stopProducer();
68
+ }
69
+ shutdown() {
70
+ this.interfaceMjpegHub.shutdown();
71
+ }
72
+ async serve(req, res) {
73
+ const nativeUrl = this.source.getNativeUrl();
74
+ const recentlyFailed = false === this.nativeAvailable && null !== this.nativeFailedAt && Date.now() - this.nativeFailedAt < NEGATIVE_CACHE_MS;
75
+ if (nativeUrl && !recentlyFailed) {
76
+ const proxied = await this.probeAndProxyNative(nativeUrl, req, res);
77
+ if (proxied) return;
78
+ }
79
+ const activeInterface = this.source.getActiveInterface();
80
+ if (activeInterface) {
81
+ const interfaceStreamStarted = await this.interfaceMjpegHub.streamRequest(req, res, activeInterface, async (startupError)=>await this.source.recoverFromPreviewError?.(startupError, 'interface MJPEG startup') ?? null);
82
+ if (interfaceStreamStarted) return;
83
+ }
84
+ if (!this.source.canTakeScreenshot()) return void res.status(500).json({
85
+ error: 'Screenshot method not available on current interface'
86
+ });
87
+ await this.streamPolling(req, res);
88
+ }
89
+ probeAndProxyNative(nativeUrl, req, res) {
90
+ return new Promise((resolve)=>{
91
+ debugMjpeg(`trying native stream from ${nativeUrl}`);
92
+ const proxyReq = external_node_http_default().get(nativeUrl, (proxyRes)=>{
93
+ const statusCode = proxyRes.statusCode ?? 0;
94
+ if (statusCode >= 400) {
95
+ this.nativeAvailable = false;
96
+ this.nativeFailedAt = Date.now();
97
+ proxyRes.resume();
98
+ debugMjpeg(`native stream returned HTTP ${statusCode}, using polling mode`);
99
+ resolve(false);
100
+ return;
101
+ }
102
+ this.nativeAvailable = true;
103
+ this.nativeFailedAt = null;
104
+ debugMjpeg('streaming via native WDA MJPEG server');
105
+ const contentType = proxyRes.headers['content-type'];
106
+ if (contentType) res.setHeader('Content-Type', contentType);
107
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
108
+ res.setHeader('Connection', 'keep-alive');
109
+ proxyRes.pipe(res);
110
+ req.on('close', ()=>proxyReq.destroy());
111
+ resolve(true);
112
+ });
113
+ proxyReq.on('error', (err)=>{
114
+ this.nativeAvailable = false;
115
+ this.nativeFailedAt = Date.now();
116
+ debugMjpeg(`native stream unavailable (${err.message}), using polling mode`);
117
+ resolve(false);
118
+ });
119
+ });
120
+ }
121
+ probeNativeLiveness(nativeUrl) {
122
+ return new Promise((resolve)=>{
123
+ const probe = external_node_http_default().get(nativeUrl, (probeRes)=>{
124
+ const statusCode = probeRes.statusCode ?? 0;
125
+ const reachable = statusCode >= 200 && statusCode < 400;
126
+ probeRes.destroy();
127
+ resolve(reachable);
128
+ });
129
+ probe.setTimeout(1000, ()=>{
130
+ probe.destroy();
131
+ resolve(false);
132
+ });
133
+ probe.on('error', ()=>resolve(false));
134
+ });
135
+ }
136
+ async streamPolling(req, res) {
137
+ const parsedFps = Number(req.query.fps);
138
+ const fps = Math.min(Math.max(Number.isNaN(parsedFps) ? DEFAULT_FPS : parsedFps, 1), MAX_FPS);
139
+ const interval = Math.round(1000 / fps);
140
+ const boundary = 'mjpeg-boundary';
141
+ debugMjpeg(`streaming via polling mode (${fps}fps)`);
142
+ res.setHeader('Content-Type', `multipart/x-mixed-replace; boundary=${boundary}`);
143
+ res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
144
+ res.setHeader('Connection', 'keep-alive');
145
+ let stopped = false;
146
+ let consecutiveErrors = 0;
147
+ const nativeUrl = this.source.getNativeUrl();
148
+ let probeTimer;
149
+ if (nativeUrl) probeTimer = setInterval(async ()=>{
150
+ if (stopped) return;
151
+ const reachable = await this.probeNativeLiveness(nativeUrl);
152
+ if (reachable && !stopped) {
153
+ debugMjpeg('native stream came online, ending polling so client reconnects');
154
+ this.nativeAvailable = true;
155
+ this.nativeFailedAt = null;
156
+ stopped = true;
157
+ try {
158
+ res.destroy();
159
+ } catch {}
160
+ }
161
+ }, NATIVE_PROBE_INTERVAL_MS);
162
+ req.on('close', ()=>{
163
+ stopped = true;
164
+ if (probeTimer) clearInterval(probeTimer);
165
+ });
166
+ while(!stopped){
167
+ if (!this.source.isAgentReady()) {
168
+ await new Promise((r)=>setTimeout(r, 200));
169
+ continue;
170
+ }
171
+ const frameStart = Date.now();
172
+ try {
173
+ const base64 = await this.source.takeScreenshot();
174
+ if (stopped) break;
175
+ consecutiveErrors = 0;
176
+ (0, external_mjpeg_hub_js_namespaceObject.writeMjpegFrame)(res, boundary, {
177
+ data: base64,
178
+ contentType: 'image/jpeg'
179
+ });
180
+ } catch (err) {
181
+ if (stopped) break;
182
+ const recoveredInterface = await this.source.recoverFromPreviewError?.(err, 'polling MJPEG frame capture');
183
+ if (recoveredInterface) {
184
+ consecutiveErrors = 0;
185
+ continue;
186
+ }
187
+ consecutiveErrors++;
188
+ if (consecutiveErrors <= ERROR_LOG_THRESHOLD) console.error('MJPEG frame error:', err);
189
+ else if (consecutiveErrors === ERROR_LOG_THRESHOLD + 1) console.error('MJPEG: suppressing further errors, retrying silently...');
190
+ const backoff = Math.min(1000 * consecutiveErrors, MAX_ERROR_BACKOFF_MS);
191
+ await new Promise((r)=>setTimeout(r, backoff));
192
+ continue;
193
+ }
194
+ const elapsed = Date.now() - frameStart;
195
+ const remaining = interval - elapsed;
196
+ if (remaining > 0) await new Promise((r)=>setTimeout(r, remaining));
197
+ }
198
+ if (probeTimer) clearInterval(probeTimer);
199
+ }
200
+ constructor(source){
201
+ _define_property(this, "source", void 0);
202
+ _define_property(this, "nativeAvailable", void 0);
203
+ _define_property(this, "nativeFailedAt", void 0);
204
+ _define_property(this, "interfaceMjpegHub", void 0);
205
+ this.source = source;
206
+ this.nativeAvailable = null;
207
+ this.nativeFailedAt = null;
208
+ this.interfaceMjpegHub = (0, external_mjpeg_hub_js_namespaceObject.createInterfaceMjpegHub)({
209
+ initialFrameTimeoutMs: INTERFACE_MJPEG_INITIAL_FRAME_TIMEOUT_MS,
210
+ idleStopMs: INTERFACE_MJPEG_IDLE_STOP_MS,
211
+ debug: debugMjpeg
212
+ });
213
+ }
214
+ }
215
+ exports.MjpegStreamHandler = __webpack_exports__.MjpegStreamHandler;
216
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
217
+ "MjpegStreamHandler"
218
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
219
+ Object.defineProperty(exports, '__esModule', {
220
+ value: true
221
+ });
222
+
223
+ //# sourceMappingURL=mjpeg-stream-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mjpeg-stream-handler.js","sources":["webpack/runtime/compat_get_default_export","webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/mjpeg-stream-handler.ts"],"sourcesContent":["// getDefaultExport function for compatibility with non-ESM modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};\n","__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import http from 'node:http';\nimport type { Agent as PageAgent } from '@midscene/core/agent';\nimport { getDebug } from '@midscene/shared/logger';\nimport type { Request, Response } from 'express';\nimport {\n type InterfaceMjpegHub,\n createInterfaceMjpegHub,\n writeMjpegFrame,\n} from './mjpeg-hub';\n\nconst debugMjpeg = getDebug('playground:mjpeg', { console: true });\n\nconst NEGATIVE_CACHE_MS = 10_000;\nconst NATIVE_PROBE_INTERVAL_MS = 3000;\nconst INTERFACE_MJPEG_INITIAL_FRAME_TIMEOUT_MS = 1500;\nconst INTERFACE_MJPEG_IDLE_STOP_MS = 2000;\n\nconst DEFAULT_FPS = 10;\nconst MAX_FPS = 30;\nconst MAX_ERROR_BACKOFF_MS = 3000;\nconst ERROR_LOG_THRESHOLD = 3;\n\ntype ActiveInterface = PageAgent['interface'];\n\n/**\n * Inputs the handler reads on every request, late-bound through callbacks\n * so a single handler instance can survive across device reconnects without\n * the server having to swap it.\n */\nexport interface MjpegStreamSource {\n /** Native MJPEG URL of the current device, or undefined if it has none. */\n getNativeUrl(): string | undefined;\n /** Active interface, used for in-process MJPEG producers such as CDP screencast. */\n getActiveInterface(): ActiveInterface | null;\n /** Polling fallback. Throws if no agent is connected. */\n takeScreenshot(): Promise<string>;\n /** Returns true when polling fallback can capture screenshots. */\n canTakeScreenshot(): boolean;\n /** Returns false while the agent is being recreated. */\n isAgentReady(): boolean;\n /** Optional recovery hook for page-session loss during preview streaming. */\n recoverFromPreviewError?(\n error: unknown,\n reason: string,\n ): Promise<ActiveInterface | null>;\n}\n\n/**\n * Owns all of the MJPEG streaming logic that used to live inline on\n * `PlaygroundServer`:\n * - Tries the device's native MJPEG URL (e.g. WDA's `iproxy 9100`).\n * - Caches a negative probe for {@link NEGATIVE_CACHE_MS} so a transient\n * unavailable WDA does not lock us into polling forever.\n * - Falls back to polling `screenshotBase64()` and emitting multipart frames.\n * - While polling, periodically re-probes the native URL and tears down\n * the polling socket the moment native comes back, so the client\n * `<img>` reconnects onto the native stream.\n *\n * State lives on the handler instance, so callers can `reset()` on device\n * reconnect to drop the cached probe result.\n */\nexport class MjpegStreamHandler {\n private nativeAvailable: boolean | null = null;\n private nativeFailedAt: number | null = null;\n private readonly interfaceMjpegHub: InterfaceMjpegHub =\n createInterfaceMjpegHub({\n initialFrameTimeoutMs: INTERFACE_MJPEG_INITIAL_FRAME_TIMEOUT_MS,\n idleStopMs: INTERFACE_MJPEG_IDLE_STOP_MS,\n debug: debugMjpeg,\n });\n\n constructor(private readonly source: MjpegStreamSource) {}\n\n /** Drop the cached probe result — call this when the agent reconnects. */\n reset(): void {\n this.nativeAvailable = null;\n this.nativeFailedAt = null;\n this.interfaceMjpegHub.stopProducer();\n }\n\n shutdown(): void {\n this.interfaceMjpegHub.shutdown();\n }\n\n async serve(req: Request, res: Response): Promise<void> {\n const nativeUrl = this.source.getNativeUrl();\n const recentlyFailed =\n this.nativeAvailable === false &&\n this.nativeFailedAt !== null &&\n Date.now() - this.nativeFailedAt < NEGATIVE_CACHE_MS;\n\n if (nativeUrl && !recentlyFailed) {\n const proxied = await this.probeAndProxyNative(nativeUrl, req, res);\n if (proxied) return;\n }\n\n const activeInterface = this.source.getActiveInterface();\n if (activeInterface) {\n const interfaceStreamStarted = await this.interfaceMjpegHub.streamRequest(\n req,\n res,\n activeInterface,\n async (startupError) =>\n (await this.source.recoverFromPreviewError?.(\n startupError,\n 'interface MJPEG startup',\n )) ?? null,\n );\n if (interfaceStreamStarted) return;\n }\n\n if (!this.source.canTakeScreenshot()) {\n res.status(500).json({\n error: 'Screenshot method not available on current interface',\n });\n return;\n }\n\n await this.streamPolling(req, res);\n }\n\n private probeAndProxyNative(\n nativeUrl: string,\n req: Request,\n res: Response,\n ): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n debugMjpeg(`trying native stream from ${nativeUrl}`);\n const proxyReq = http.get(nativeUrl, (proxyRes) => {\n const statusCode = proxyRes.statusCode ?? 0;\n if (statusCode >= 400) {\n this.nativeAvailable = false;\n this.nativeFailedAt = Date.now();\n proxyRes.resume();\n debugMjpeg(\n `native stream returned HTTP ${statusCode}, using polling mode`,\n );\n resolve(false);\n return;\n }\n this.nativeAvailable = true;\n this.nativeFailedAt = null;\n debugMjpeg('streaming via native WDA MJPEG server');\n const contentType = proxyRes.headers['content-type'];\n if (contentType) res.setHeader('Content-Type', contentType);\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n res.setHeader('Connection', 'keep-alive');\n proxyRes.pipe(res);\n req.on('close', () => proxyReq.destroy());\n resolve(true);\n });\n proxyReq.on('error', (err) => {\n this.nativeAvailable = false;\n this.nativeFailedAt = Date.now();\n debugMjpeg(\n `native stream unavailable (${err.message}), using polling mode`,\n );\n resolve(false);\n });\n });\n }\n\n private probeNativeLiveness(nativeUrl: string): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const probe = http.get(nativeUrl, (probeRes) => {\n const statusCode = probeRes.statusCode ?? 0;\n const reachable = statusCode >= 200 && statusCode < 400;\n probeRes.destroy();\n resolve(reachable);\n });\n probe.setTimeout(1000, () => {\n probe.destroy();\n resolve(false);\n });\n probe.on('error', () => resolve(false));\n });\n }\n\n private async streamPolling(req: Request, res: Response): Promise<void> {\n const parsedFps = Number(req.query.fps);\n const fps = Math.min(\n Math.max(Number.isNaN(parsedFps) ? DEFAULT_FPS : parsedFps, 1),\n MAX_FPS,\n );\n const interval = Math.round(1000 / fps);\n const boundary = 'mjpeg-boundary';\n debugMjpeg(`streaming via polling mode (${fps}fps)`);\n\n res.setHeader(\n 'Content-Type',\n `multipart/x-mixed-replace; boundary=${boundary}`,\n );\n res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');\n res.setHeader('Connection', 'keep-alive');\n\n let stopped = false;\n let consecutiveErrors = 0;\n\n // While in polling mode, periodically re-probe the native URL. As soon\n // as it becomes reachable, destroy this socket so the client's <img>\n // fires onError and reconnects onto the native stream. (res.end() leaves\n // the multipart frame visually frozen in some browsers.)\n const nativeUrl = this.source.getNativeUrl();\n let probeTimer: ReturnType<typeof setInterval> | undefined;\n if (nativeUrl) {\n probeTimer = setInterval(async () => {\n if (stopped) return;\n const reachable = await this.probeNativeLiveness(nativeUrl);\n if (reachable && !stopped) {\n debugMjpeg(\n 'native stream came online, ending polling so client reconnects',\n );\n this.nativeAvailable = true;\n this.nativeFailedAt = null;\n stopped = true;\n try {\n res.destroy();\n } catch {\n /* socket already closed */\n }\n }\n }, NATIVE_PROBE_INTERVAL_MS);\n }\n req.on('close', () => {\n stopped = true;\n if (probeTimer) clearInterval(probeTimer);\n });\n\n while (!stopped) {\n if (!this.source.isAgentReady()) {\n await new Promise((r) => setTimeout(r, 200));\n continue;\n }\n\n const frameStart = Date.now();\n try {\n const base64 = await this.source.takeScreenshot();\n if (stopped) break;\n consecutiveErrors = 0;\n\n writeMjpegFrame(res, boundary, {\n data: base64,\n contentType: 'image/jpeg',\n });\n } catch (err) {\n if (stopped) break;\n const recoveredInterface = await this.source.recoverFromPreviewError?.(\n err,\n 'polling MJPEG frame capture',\n );\n if (recoveredInterface) {\n consecutiveErrors = 0;\n continue;\n }\n consecutiveErrors++;\n if (consecutiveErrors <= ERROR_LOG_THRESHOLD) {\n console.error('MJPEG frame error:', err);\n } else if (consecutiveErrors === ERROR_LOG_THRESHOLD + 1) {\n console.error(\n 'MJPEG: suppressing further errors, retrying silently...',\n );\n }\n const backoff = Math.min(\n 1000 * consecutiveErrors,\n MAX_ERROR_BACKOFF_MS,\n );\n await new Promise((r) => setTimeout(r, backoff));\n continue;\n }\n\n const elapsed = Date.now() - frameStart;\n const remaining = interval - elapsed;\n if (remaining > 0) await new Promise((r) => setTimeout(r, remaining));\n }\n if (probeTimer) clearInterval(probeTimer);\n }\n}\n"],"names":["__webpack_require__","module","getter","definition","key","Object","obj","prop","Symbol","debugMjpeg","getDebug","NEGATIVE_CACHE_MS","NATIVE_PROBE_INTERVAL_MS","INTERFACE_MJPEG_INITIAL_FRAME_TIMEOUT_MS","INTERFACE_MJPEG_IDLE_STOP_MS","DEFAULT_FPS","MAX_FPS","MAX_ERROR_BACKOFF_MS","ERROR_LOG_THRESHOLD","MjpegStreamHandler","req","res","nativeUrl","recentlyFailed","Date","proxied","activeInterface","interfaceStreamStarted","startupError","Promise","resolve","proxyReq","http","proxyRes","statusCode","contentType","err","probe","probeRes","reachable","parsedFps","Number","fps","Math","interval","boundary","stopped","consecutiveErrors","probeTimer","setInterval","clearInterval","r","setTimeout","frameStart","base64","writeMjpegFrame","recoveredInterface","console","backoff","elapsed","remaining","source","createInterfaceMjpegHub"],"mappings":"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"}
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __webpack_require__ = {};
3
+ (()=>{
4
+ __webpack_require__.d = (exports1, definition)=>{
5
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
+ enumerable: true,
7
+ get: definition[key]
8
+ });
9
+ };
10
+ })();
11
+ (()=>{
12
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
13
+ })();
14
+ (()=>{
15
+ __webpack_require__.r = (exports1)=>{
16
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
17
+ value: 'Module'
18
+ });
19
+ Object.defineProperty(exports1, '__esModule', {
20
+ value: true
21
+ });
22
+ };
23
+ })();
24
+ var __webpack_exports__ = {};
25
+ __webpack_require__.r(__webpack_exports__);
26
+ __webpack_require__.d(__webpack_exports__, {
27
+ dispatchPointer: ()=>dispatchPointer,
28
+ PointerInputError: ()=>PointerInputError
29
+ });
30
+ const device_namespaceObject = require("@midscene/core/device");
31
+ function _define_property(obj, key, value) {
32
+ if (key in obj) Object.defineProperty(obj, key, {
33
+ value: value,
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true
37
+ });
38
+ else obj[key] = value;
39
+ return obj;
40
+ }
41
+ class PointerInputError extends Error {
42
+ constructor(message, statusCode){
43
+ super(message), _define_property(this, "statusCode", void 0), this.statusCode = statusCode;
44
+ this.name = 'PointerInputError';
45
+ }
46
+ }
47
+ function requireNumber(value, field) {
48
+ if ('number' != typeof value || Number.isNaN(value)) throw new PointerInputError(`${field} must be a number`, 400);
49
+ return value;
50
+ }
51
+ function optionalNumber(value, field) {
52
+ if (void 0 === value) return;
53
+ return requireNumber(value, field);
54
+ }
55
+ function requireString(value, field) {
56
+ if ('string' != typeof value) throw new PointerInputError(`${field} must be a string`, 400);
57
+ return value;
58
+ }
59
+ function requirePoint(body, xField = 'x', yField = 'y') {
60
+ return {
61
+ x: requireNumber(body[xField], xField),
62
+ y: requireNumber(body[yField], yField)
63
+ };
64
+ }
65
+ function ensureCapability(fn, actionType) {
66
+ if ('function' != typeof fn) throw new PointerInputError(`${actionType} is not supported on this device`, 404);
67
+ return fn;
68
+ }
69
+ function getPointerInput(input) {
70
+ if (!input.pointer) throw new PointerInputError('Pointer input is not supported on this device', 404);
71
+ return input.pointer;
72
+ }
73
+ function getKeyboardInput(input) {
74
+ if (!input.keyboard) throw new PointerInputError('Keyboard input is not supported on this device', 404);
75
+ return input.keyboard;
76
+ }
77
+ function getTouchInput(input) {
78
+ if (!input.touch) throw new PointerInputError('Touch input is not supported on this device', 404);
79
+ return input.touch;
80
+ }
81
+ async function dispatchPointer(input, body, getScreenSize) {
82
+ const { actionType } = body;
83
+ if ('string' != typeof actionType || !actionType) throw new PointerInputError('actionType is required', 400);
84
+ switch(actionType){
85
+ case 'Tap':
86
+ {
87
+ const pointer = getPointerInput(input);
88
+ return ensureCapability(pointer.tap, 'Tap')(requirePoint(body), {
89
+ duration: optionalNumber(body.duration, 'duration')
90
+ });
91
+ }
92
+ case 'DoubleClick':
93
+ {
94
+ const pointer = getPointerInput(input);
95
+ return ensureCapability(pointer.doubleClick, 'DoubleClick')(requirePoint(body));
96
+ }
97
+ case 'LongPress':
98
+ {
99
+ const pointer = getPointerInput(input);
100
+ return ensureCapability(pointer.longPress, 'LongPress')(requirePoint(body), {
101
+ duration: optionalNumber(body.duration, 'duration')
102
+ });
103
+ }
104
+ case 'Swipe':
105
+ {
106
+ const touch = getTouchInput(input);
107
+ return ensureCapability(touch.swipe, 'Swipe')(requirePoint(body), requirePoint(body, 'endX', 'endY'), {
108
+ duration: optionalNumber(body.duration, 'duration'),
109
+ repeat: optionalNumber(body.repeat, 'repeat')
110
+ });
111
+ }
112
+ case 'DragAndDrop':
113
+ {
114
+ const pointer = getPointerInput(input);
115
+ return ensureCapability(pointer.dragAndDrop, 'DragAndDrop')(requirePoint(body), requirePoint(body, 'endX', 'endY'));
116
+ }
117
+ case 'KeyboardPress':
118
+ {
119
+ const keyboard = getKeyboardInput(input);
120
+ return ensureCapability(keyboard.keyboardPress, 'KeyboardPress')(requireString(body.keyName, 'keyName'));
121
+ }
122
+ case 'Input':
123
+ {
124
+ const keyboard = getKeyboardInput(input);
125
+ const value = requireString(body.value, 'value');
126
+ const at = 'number' == typeof body.x && 'number' == typeof body.y ? requirePoint(body) : void 0;
127
+ const mode = 'string' == typeof body.mode ? body.mode : void 0;
128
+ const autoDismissKeyboard = 'boolean' == typeof body.autoDismissKeyboard ? body.autoDismissKeyboard : void 0;
129
+ const target = at ? {
130
+ center: [
131
+ at.x,
132
+ at.y
133
+ ],
134
+ rect: {
135
+ left: at.x,
136
+ top: at.y,
137
+ width: 1,
138
+ height: 1
139
+ },
140
+ description: 'manual input target'
141
+ } : void 0;
142
+ if ('clear' === mode) return void await ensureCapability(keyboard.clearInput, 'ClearInput')(target);
143
+ if (!value) return;
144
+ return ensureCapability(keyboard.typeText, 'Input')(value, {
145
+ autoDismissKeyboard,
146
+ target,
147
+ replace: 'typeOnly' !== mode
148
+ });
149
+ }
150
+ case 'Pinch':
151
+ {
152
+ const center = requirePoint(body);
153
+ const direction = (()=>{
154
+ const d = body.direction;
155
+ if ('in' !== d && 'out' !== d) throw new PointerInputError('direction must be "in" or "out"', 400);
156
+ return d;
157
+ })();
158
+ const touch = getTouchInput(input);
159
+ const { startDistance, endDistance, duration } = (0, device_namespaceObject.normalizePinchParam)({
160
+ locate: {
161
+ center: [
162
+ center.x,
163
+ center.y
164
+ ],
165
+ rect: {
166
+ left: center.x,
167
+ top: center.y,
168
+ width: 1,
169
+ height: 1
170
+ },
171
+ description: 'manual pinch target'
172
+ },
173
+ direction,
174
+ distance: optionalNumber(body.distance, 'distance'),
175
+ duration: optionalNumber(body.duration, 'duration')
176
+ }, await getScreenSize());
177
+ return ensureCapability(touch.pinch, 'Pinch')(center, {
178
+ startDistance,
179
+ endDistance,
180
+ duration
181
+ });
182
+ }
183
+ default:
184
+ throw new PointerInputError(`Unknown actionType "${actionType}"`, 404);
185
+ }
186
+ }
187
+ exports.PointerInputError = __webpack_exports__.PointerInputError;
188
+ exports.dispatchPointer = __webpack_exports__.dispatchPointer;
189
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
190
+ "PointerInputError",
191
+ "dispatchPointer"
192
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
193
+ Object.defineProperty(exports, '__esModule', {
194
+ value: true
195
+ });
196
+
197
+ //# sourceMappingURL=pointer-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer-dispatch.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../src/pointer-dispatch.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type {\n InputPrimitives,\n KeyboardInputPrimitives,\n PointerInputPrimitives,\n PointerPoint,\n TouchInputPrimitives,\n} from '@midscene/core/device';\nimport { normalizePinchParam } from '@midscene/core/device';\n\n/**\n * Thrown when an /interact request is malformed (missing field, wrong type)\n * or names an action / capability that the connected device does not support.\n * The route handler maps {400, 404} onto the HTTP response.\n */\nexport class PointerInputError extends Error {\n constructor(\n message: string,\n public statusCode: 400 | 404,\n ) {\n super(message);\n this.name = 'PointerInputError';\n }\n}\n\nfunction requireNumber(value: unknown, field: string): number {\n if (typeof value !== 'number' || Number.isNaN(value)) {\n throw new PointerInputError(`${field} must be a number`, 400);\n }\n return value;\n}\n\nfunction optionalNumber(value: unknown, field: string): number | undefined {\n if (value === undefined) return undefined;\n return requireNumber(value, field);\n}\n\nfunction requireString(value: unknown, field: string): string {\n if (typeof value !== 'string') {\n throw new PointerInputError(`${field} must be a string`, 400);\n }\n return value;\n}\n\nfunction requirePoint(\n body: Record<string, unknown>,\n xField: 'x' | 'endX' = 'x',\n yField: 'y' | 'endY' = 'y',\n): PointerPoint {\n return {\n x: requireNumber(body[xField], xField),\n y: requireNumber(body[yField], yField),\n };\n}\n\nfunction ensureCapability<T>(\n fn: T | undefined,\n actionType: string,\n): NonNullable<T> {\n if (typeof fn !== 'function') {\n throw new PointerInputError(\n `${actionType} is not supported on this device`,\n 404,\n );\n }\n return fn as NonNullable<T>;\n}\n\nfunction getPointerInput(input: InputPrimitives): PointerInputPrimitives {\n if (!input.pointer) {\n throw new PointerInputError(\n 'Pointer input is not supported on this device',\n 404,\n );\n }\n return input.pointer;\n}\n\nfunction getKeyboardInput(input: InputPrimitives): KeyboardInputPrimitives {\n if (!input.keyboard) {\n throw new PointerInputError(\n 'Keyboard input is not supported on this device',\n 404,\n );\n }\n return input.keyboard;\n}\n\nfunction getTouchInput(input: InputPrimitives): TouchInputPrimitives {\n if (!input.touch) {\n throw new PointerInputError(\n 'Touch input is not supported on this device',\n 404,\n );\n }\n return input.touch;\n}\n\n/**\n * Translate an `/interact` request body into device input primitive calls.\n *\n * The dispatcher is deliberately a flat switch: each case is HTTP-protocol\n * adaptation (parse + range-check fields, hand them to the typed primitive),\n * not platform business logic.\n */\nexport async function dispatchPointer(\n input: InputPrimitives,\n body: Record<string, unknown>,\n getScreenSize: () => Promise<{ width: number; height: number }>,\n): Promise<void> {\n const { actionType } = body;\n if (typeof actionType !== 'string' || !actionType) {\n throw new PointerInputError('actionType is required', 400);\n }\n\n switch (actionType) {\n case 'Tap': {\n const pointer = getPointerInput(input);\n return ensureCapability(pointer.tap, 'Tap')(requirePoint(body), {\n duration: optionalNumber(body.duration, 'duration'),\n });\n }\n\n case 'DoubleClick': {\n const pointer = getPointerInput(input);\n return ensureCapability(\n pointer.doubleClick,\n 'DoubleClick',\n )(requirePoint(body));\n }\n\n case 'LongPress': {\n const pointer = getPointerInput(input);\n return ensureCapability(pointer.longPress, 'LongPress')(\n requirePoint(body),\n {\n duration: optionalNumber(body.duration, 'duration'),\n },\n );\n }\n\n case 'Swipe': {\n const touch = getTouchInput(input);\n return ensureCapability(touch.swipe, 'Swipe')(\n requirePoint(body),\n requirePoint(body, 'endX', 'endY'),\n {\n duration: optionalNumber(body.duration, 'duration'),\n repeat: optionalNumber(body.repeat, 'repeat'),\n },\n );\n }\n\n case 'DragAndDrop': {\n const pointer = getPointerInput(input);\n return ensureCapability(pointer.dragAndDrop, 'DragAndDrop')(\n requirePoint(body),\n requirePoint(body, 'endX', 'endY'),\n );\n }\n\n case 'KeyboardPress': {\n const keyboard = getKeyboardInput(input);\n return ensureCapability(\n keyboard.keyboardPress,\n 'KeyboardPress',\n )(requireString(body.keyName, 'keyName'));\n }\n\n case 'Input': {\n const keyboard = getKeyboardInput(input);\n const value = requireString(body.value, 'value');\n const at =\n typeof body.x === 'number' && typeof body.y === 'number'\n ? requirePoint(body)\n : undefined;\n const mode =\n typeof body.mode === 'string'\n ? (body.mode as 'replace' | 'clear' | 'typeOnly')\n : undefined;\n const autoDismissKeyboard =\n typeof body.autoDismissKeyboard === 'boolean'\n ? body.autoDismissKeyboard\n : undefined;\n const target = at\n ? {\n center: [at.x, at.y] as [number, number],\n rect: { left: at.x, top: at.y, width: 1, height: 1 },\n description: 'manual input target',\n }\n : undefined;\n if (mode === 'clear') {\n await ensureCapability(keyboard.clearInput, 'ClearInput')(target);\n return;\n }\n if (!value) return;\n return ensureCapability(keyboard.typeText, 'Input')(value, {\n autoDismissKeyboard,\n target,\n replace: mode !== 'typeOnly',\n });\n }\n\n case 'Pinch': {\n const center = requirePoint(body);\n const direction = ((): 'in' | 'out' => {\n const d = body.direction;\n if (d !== 'in' && d !== 'out') {\n throw new PointerInputError('direction must be \"in\" or \"out\"', 400);\n }\n return d;\n })();\n const touch = getTouchInput(input);\n const { startDistance, endDistance, duration } = normalizePinchParam(\n {\n locate: {\n center: [center.x, center.y],\n rect: { left: center.x, top: center.y, width: 1, height: 1 },\n description: 'manual pinch target',\n },\n direction,\n distance: optionalNumber(body.distance, 'distance'),\n duration: optionalNumber(body.duration, 'duration'),\n },\n await getScreenSize(),\n );\n return ensureCapability(touch.pinch, 'Pinch')(center, {\n startDistance,\n endDistance,\n duration,\n });\n }\n\n default:\n throw new PointerInputError(`Unknown actionType \"${actionType}\"`, 404);\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","PointerInputError","Error","message","statusCode","requireNumber","value","field","Number","optionalNumber","undefined","requireString","requirePoint","body","xField","yField","ensureCapability","fn","actionType","getPointerInput","input","getKeyboardInput","getTouchInput","dispatchPointer","getScreenSize","pointer","touch","keyboard","at","mode","autoDismissKeyboard","target","center","direction","d","startDistance","endDistance","duration","normalizePinchParam"],"mappings":"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"}