@midscene/android-playground 1.12.4 → 1.12.5-beta-20260907092148.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/dist/es/bin.mjs CHANGED
@@ -47,6 +47,13 @@ const androidPlaygroundPlatform = definePlaygroundPlatform({
47
47
  options?.scrcpyPort ? Promise.resolve(options.scrcpyPort) : findAvailablePort(SCRCPY_SERVER_PORT)
48
48
  ]);
49
49
  const scrcpyPort = resolvedScrcpyPort;
50
+ const scrcpyHost = options?.scrcpyServer?.host;
51
+ const scrcpyPreviewOptions = {
52
+ scrcpyPort,
53
+ ...scrcpyHost ? {
54
+ scrcpyHost
55
+ } : {}
56
+ };
50
57
  if (playgroundPort !== PLAYGROUND_SERVER_PORT) console.log(`⚠️ Port ${PLAYGROUND_SERVER_PORT} is busy, using port ${playgroundPort} instead`);
51
58
  if (scrcpyPort !== SCRCPY_SERVER_PORT) console.log(`⚠️ Port ${SCRCPY_SERVER_PORT} is busy, using port ${scrcpyPort} instead`);
52
59
  const sessionManager = {
@@ -95,9 +102,7 @@ const androidPlaygroundPlatform = definePlaygroundPlatform({
95
102
  return {
96
103
  agent,
97
104
  agentFactory: connectAgent,
98
- preview: createScrcpyPreviewDescriptor({
99
- scrcpyPort
100
- }, {
105
+ preview: createScrcpyPreviewDescriptor(scrcpyPreviewOptions, {
101
106
  title: 'Android device preview'
102
107
  }),
103
108
  displayName: deviceId,
@@ -132,9 +137,7 @@ const androidPlaygroundPlatform = definePlaygroundPlatform({
132
137
  server.scrcpyPort = scrcpyPort;
133
138
  }
134
139
  },
135
- preview: createScrcpyPreviewDescriptor({
136
- scrcpyPort
137
- }, {
140
+ preview: createScrcpyPreviewDescriptor(scrcpyPreviewOptions, {
138
141
  title: 'Android device preview'
139
142
  }),
140
143
  metadata: {
@@ -612,11 +615,16 @@ class ScrcpyServer {
612
615
  });
613
616
  }
614
617
  async launch(port) {
615
- this.port = port || this.defaultPort;
616
- return new Promise((resolve)=>{
618
+ this.port = port ?? this.defaultPort;
619
+ return new Promise((resolve, reject)=>{
617
620
  const listenPort = this.port ?? this.defaultPort;
618
- this.httpServer.listen(listenPort, '0.0.0.0', ()=>{
619
- console.log(`Scrcpy server running at: http://0.0.0.0:${this.port}`);
621
+ const onError = (error)=>reject(error);
622
+ this.httpServer.once('error', onError);
623
+ this.httpServer.listen(listenPort, this.host, ()=>{
624
+ this.httpServer.off('error', onError);
625
+ const address = this.httpServer.address();
626
+ if (address && 'string' != typeof address) this.port = address.port;
627
+ console.log(`Scrcpy server running at: http://${this.host}:${this.port}`);
620
628
  this.startDeviceMonitoring();
621
629
  resolve(this);
622
630
  });
@@ -663,9 +671,12 @@ class ScrcpyServer {
663
671
  scrcpy_server_define_property(this, "adbClient", null);
664
672
  scrcpy_server_define_property(this, "currentDeviceId", null);
665
673
  scrcpy_server_define_property(this, "devicePollInterval", null);
674
+ scrcpy_server_define_property(this, "host", void 0);
666
675
  scrcpy_server_define_property(this, "deviceListSource", void 0);
667
676
  scrcpy_server_define_property(this, "deviceListSourceUnsubscribe", void 0);
668
677
  scrcpy_server_define_property(this, "lastDeviceList", '');
678
+ this.host = options.host ?? '127.0.0.1';
679
+ if (!this.host.trim()) throw new Error('Scrcpy host must not be empty');
669
680
  this.deviceListSource = options.deviceListSource;
670
681
  this.app = express();
671
682
  this.httpServer = createServer(this.app);
@@ -697,7 +708,9 @@ const bin_staticDir = node_path.join(__dirname, '../../static');
697
708
  const main = async ()=>{
698
709
  const { default: open } = await import("open");
699
710
  try {
700
- const scrcpyServer = new ScrcpyServer();
711
+ const scrcpyServer = new ScrcpyServer({
712
+ host: process.env.MIDSCENE_SCRCPY_HOST
713
+ });
701
714
  const prepared = await androidPlaygroundPlatform.prepare({
702
715
  staticDir: bin_staticDir,
703
716
  scrcpyServer
package/dist/es/index.mjs CHANGED
@@ -47,6 +47,13 @@ const androidPlaygroundPlatform = definePlaygroundPlatform({
47
47
  options?.scrcpyPort ? Promise.resolve(options.scrcpyPort) : findAvailablePort(SCRCPY_SERVER_PORT)
48
48
  ]);
49
49
  const scrcpyPort = resolvedScrcpyPort;
50
+ const scrcpyHost = options?.scrcpyServer?.host;
51
+ const scrcpyPreviewOptions = {
52
+ scrcpyPort,
53
+ ...scrcpyHost ? {
54
+ scrcpyHost
55
+ } : {}
56
+ };
50
57
  if (playgroundPort !== PLAYGROUND_SERVER_PORT) console.log(`⚠️ Port ${PLAYGROUND_SERVER_PORT} is busy, using port ${playgroundPort} instead`);
51
58
  if (scrcpyPort !== SCRCPY_SERVER_PORT) console.log(`⚠️ Port ${SCRCPY_SERVER_PORT} is busy, using port ${scrcpyPort} instead`);
52
59
  const sessionManager = {
@@ -95,9 +102,7 @@ const androidPlaygroundPlatform = definePlaygroundPlatform({
95
102
  return {
96
103
  agent,
97
104
  agentFactory: connectAgent,
98
- preview: createScrcpyPreviewDescriptor({
99
- scrcpyPort
100
- }, {
105
+ preview: createScrcpyPreviewDescriptor(scrcpyPreviewOptions, {
101
106
  title: 'Android device preview'
102
107
  }),
103
108
  displayName: deviceId,
@@ -132,9 +137,7 @@ const androidPlaygroundPlatform = definePlaygroundPlatform({
132
137
  server.scrcpyPort = scrcpyPort;
133
138
  }
134
139
  },
135
- preview: createScrcpyPreviewDescriptor({
136
- scrcpyPort
137
- }, {
140
+ preview: createScrcpyPreviewDescriptor(scrcpyPreviewOptions, {
138
141
  title: 'Android device preview'
139
142
  }),
140
143
  metadata: {
@@ -612,11 +615,16 @@ class ScrcpyServer {
612
615
  });
613
616
  }
614
617
  async launch(port) {
615
- this.port = port || this.defaultPort;
616
- return new Promise((resolve)=>{
618
+ this.port = port ?? this.defaultPort;
619
+ return new Promise((resolve, reject)=>{
617
620
  const listenPort = this.port ?? this.defaultPort;
618
- this.httpServer.listen(listenPort, '0.0.0.0', ()=>{
619
- console.log(`Scrcpy server running at: http://0.0.0.0:${this.port}`);
621
+ const onError = (error)=>reject(error);
622
+ this.httpServer.once('error', onError);
623
+ this.httpServer.listen(listenPort, this.host, ()=>{
624
+ this.httpServer.off('error', onError);
625
+ const address = this.httpServer.address();
626
+ if (address && 'string' != typeof address) this.port = address.port;
627
+ console.log(`Scrcpy server running at: http://${this.host}:${this.port}`);
620
628
  this.startDeviceMonitoring();
621
629
  resolve(this);
622
630
  });
@@ -663,9 +671,12 @@ class ScrcpyServer {
663
671
  scrcpy_server_define_property(this, "adbClient", null);
664
672
  scrcpy_server_define_property(this, "currentDeviceId", null);
665
673
  scrcpy_server_define_property(this, "devicePollInterval", null);
674
+ scrcpy_server_define_property(this, "host", void 0);
666
675
  scrcpy_server_define_property(this, "deviceListSource", void 0);
667
676
  scrcpy_server_define_property(this, "deviceListSourceUnsubscribe", void 0);
668
677
  scrcpy_server_define_property(this, "lastDeviceList", '');
678
+ this.host = options.host ?? '127.0.0.1';
679
+ if (!this.host.trim()) throw new Error('Scrcpy host must not be empty');
669
680
  this.deviceListSource = options.deviceListSource;
670
681
  this.app = express();
671
682
  this.httpServer = createServer(this.app);
package/dist/lib/bin.js CHANGED
@@ -63,6 +63,13 @@ const androidPlaygroundPlatform = (0, playground_namespaceObject.definePlaygroun
63
63
  options?.scrcpyPort ? Promise.resolve(options.scrcpyPort) : (0, node_namespaceObject.findAvailablePort)(constants_namespaceObject.SCRCPY_SERVER_PORT)
64
64
  ]);
65
65
  const scrcpyPort = resolvedScrcpyPort;
66
+ const scrcpyHost = options?.scrcpyServer?.host;
67
+ const scrcpyPreviewOptions = {
68
+ scrcpyPort,
69
+ ...scrcpyHost ? {
70
+ scrcpyHost
71
+ } : {}
72
+ };
66
73
  if (playgroundPort !== constants_namespaceObject.PLAYGROUND_SERVER_PORT) console.log(`⚠️ Port ${constants_namespaceObject.PLAYGROUND_SERVER_PORT} is busy, using port ${playgroundPort} instead`);
67
74
  if (scrcpyPort !== constants_namespaceObject.SCRCPY_SERVER_PORT) console.log(`⚠️ Port ${constants_namespaceObject.SCRCPY_SERVER_PORT} is busy, using port ${scrcpyPort} instead`);
68
75
  const sessionManager = {
@@ -111,9 +118,7 @@ const androidPlaygroundPlatform = (0, playground_namespaceObject.definePlaygroun
111
118
  return {
112
119
  agent,
113
120
  agentFactory: connectAgent,
114
- preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)({
115
- scrcpyPort
116
- }, {
121
+ preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)(scrcpyPreviewOptions, {
117
122
  title: 'Android device preview'
118
123
  }),
119
124
  displayName: deviceId,
@@ -148,9 +153,7 @@ const androidPlaygroundPlatform = (0, playground_namespaceObject.definePlaygroun
148
153
  server.scrcpyPort = scrcpyPort;
149
154
  }
150
155
  },
151
- preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)({
152
- scrcpyPort
153
- }, {
156
+ preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)(scrcpyPreviewOptions, {
154
157
  title: 'Android device preview'
155
158
  }),
156
159
  metadata: {
@@ -638,11 +641,16 @@ class ScrcpyServer {
638
641
  });
639
642
  }
640
643
  async launch(port) {
641
- this.port = port || this.defaultPort;
642
- return new Promise((resolve)=>{
644
+ this.port = port ?? this.defaultPort;
645
+ return new Promise((resolve, reject)=>{
643
646
  const listenPort = this.port ?? this.defaultPort;
644
- this.httpServer.listen(listenPort, '0.0.0.0', ()=>{
645
- console.log(`Scrcpy server running at: http://0.0.0.0:${this.port}`);
647
+ const onError = (error)=>reject(error);
648
+ this.httpServer.once('error', onError);
649
+ this.httpServer.listen(listenPort, this.host, ()=>{
650
+ this.httpServer.off('error', onError);
651
+ const address = this.httpServer.address();
652
+ if (address && 'string' != typeof address) this.port = address.port;
653
+ console.log(`Scrcpy server running at: http://${this.host}:${this.port}`);
646
654
  this.startDeviceMonitoring();
647
655
  resolve(this);
648
656
  });
@@ -689,9 +697,12 @@ class ScrcpyServer {
689
697
  scrcpy_server_define_property(this, "adbClient", null);
690
698
  scrcpy_server_define_property(this, "currentDeviceId", null);
691
699
  scrcpy_server_define_property(this, "devicePollInterval", null);
700
+ scrcpy_server_define_property(this, "host", void 0);
692
701
  scrcpy_server_define_property(this, "deviceListSource", void 0);
693
702
  scrcpy_server_define_property(this, "deviceListSourceUnsubscribe", void 0);
694
703
  scrcpy_server_define_property(this, "lastDeviceList", '');
704
+ this.host = options.host ?? '127.0.0.1';
705
+ if (!this.host.trim()) throw new Error('Scrcpy host must not be empty');
695
706
  this.deviceListSource = options.deviceListSource;
696
707
  this.app = external_express_default()();
697
708
  this.httpServer = (0, external_node_http_namespaceObject.createServer)(this.app);
@@ -723,7 +734,9 @@ const bin_staticDir = external_node_path_default().join(__dirname, '../../static
723
734
  const main = async ()=>{
724
735
  const { default: open } = await import("open");
725
736
  try {
726
- const scrcpyServer = new ScrcpyServer();
737
+ const scrcpyServer = new ScrcpyServer({
738
+ host: process.env.MIDSCENE_SCRCPY_HOST
739
+ });
727
740
  const prepared = await androidPlaygroundPlatform.prepare({
728
741
  staticDir: bin_staticDir,
729
742
  scrcpyServer
package/dist/lib/index.js CHANGED
@@ -78,6 +78,13 @@ const androidPlaygroundPlatform = (0, playground_namespaceObject.definePlaygroun
78
78
  options?.scrcpyPort ? Promise.resolve(options.scrcpyPort) : (0, node_namespaceObject.findAvailablePort)(constants_namespaceObject.SCRCPY_SERVER_PORT)
79
79
  ]);
80
80
  const scrcpyPort = resolvedScrcpyPort;
81
+ const scrcpyHost = options?.scrcpyServer?.host;
82
+ const scrcpyPreviewOptions = {
83
+ scrcpyPort,
84
+ ...scrcpyHost ? {
85
+ scrcpyHost
86
+ } : {}
87
+ };
81
88
  if (playgroundPort !== constants_namespaceObject.PLAYGROUND_SERVER_PORT) console.log(`⚠️ Port ${constants_namespaceObject.PLAYGROUND_SERVER_PORT} is busy, using port ${playgroundPort} instead`);
82
89
  if (scrcpyPort !== constants_namespaceObject.SCRCPY_SERVER_PORT) console.log(`⚠️ Port ${constants_namespaceObject.SCRCPY_SERVER_PORT} is busy, using port ${scrcpyPort} instead`);
83
90
  const sessionManager = {
@@ -126,9 +133,7 @@ const androidPlaygroundPlatform = (0, playground_namespaceObject.definePlaygroun
126
133
  return {
127
134
  agent,
128
135
  agentFactory: connectAgent,
129
- preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)({
130
- scrcpyPort
131
- }, {
136
+ preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)(scrcpyPreviewOptions, {
132
137
  title: 'Android device preview'
133
138
  }),
134
139
  displayName: deviceId,
@@ -163,9 +168,7 @@ const androidPlaygroundPlatform = (0, playground_namespaceObject.definePlaygroun
163
168
  server.scrcpyPort = scrcpyPort;
164
169
  }
165
170
  },
166
- preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)({
167
- scrcpyPort
168
- }, {
171
+ preview: (0, playground_namespaceObject.createScrcpyPreviewDescriptor)(scrcpyPreviewOptions, {
169
172
  title: 'Android device preview'
170
173
  }),
171
174
  metadata: {
@@ -653,11 +656,16 @@ class ScrcpyServer {
653
656
  });
654
657
  }
655
658
  async launch(port) {
656
- this.port = port || this.defaultPort;
657
- return new Promise((resolve)=>{
659
+ this.port = port ?? this.defaultPort;
660
+ return new Promise((resolve, reject)=>{
658
661
  const listenPort = this.port ?? this.defaultPort;
659
- this.httpServer.listen(listenPort, '0.0.0.0', ()=>{
660
- console.log(`Scrcpy server running at: http://0.0.0.0:${this.port}`);
662
+ const onError = (error)=>reject(error);
663
+ this.httpServer.once('error', onError);
664
+ this.httpServer.listen(listenPort, this.host, ()=>{
665
+ this.httpServer.off('error', onError);
666
+ const address = this.httpServer.address();
667
+ if (address && 'string' != typeof address) this.port = address.port;
668
+ console.log(`Scrcpy server running at: http://${this.host}:${this.port}`);
661
669
  this.startDeviceMonitoring();
662
670
  resolve(this);
663
671
  });
@@ -704,9 +712,12 @@ class ScrcpyServer {
704
712
  scrcpy_server_define_property(this, "adbClient", null);
705
713
  scrcpy_server_define_property(this, "currentDeviceId", null);
706
714
  scrcpy_server_define_property(this, "devicePollInterval", null);
715
+ scrcpy_server_define_property(this, "host", void 0);
707
716
  scrcpy_server_define_property(this, "deviceListSource", void 0);
708
717
  scrcpy_server_define_property(this, "deviceListSourceUnsubscribe", void 0);
709
718
  scrcpy_server_define_property(this, "lastDeviceList", '');
719
+ this.host = options.host ?? '127.0.0.1';
720
+ if (!this.host.trim()) throw new Error('Scrcpy host must not be empty');
710
721
  this.deviceListSource = options.deviceListSource;
711
722
  this.app = external_express_default()();
712
723
  this.httpServer = (0, external_node_http_namespaceObject.createServer)(this.app);
@@ -1,5 +1,7 @@
1
1
  import { type AndroidAgentOpt } from '@midscene/android';
2
2
  export interface ScrcpyServerController {
3
+ /** Bind host, used to connect local Playground pages to this sidecar. */
4
+ readonly host?: string;
3
5
  currentDeviceId: string | null;
4
6
  launch(port?: number): Promise<unknown>;
5
7
  close(): unknown;
@@ -19,6 +19,8 @@ export interface ScrcpyDeviceListSource {
19
19
  subscribe(listener: (devices: ScrcpyListedDevice[]) => void): () => void;
20
20
  }
21
21
  export interface ScrcpyServerOptions {
22
+ /** Defaults to loopback. Set explicitly to expose previews remotely. */
23
+ host?: string;
22
24
  deviceListSource?: ScrcpyDeviceListSource;
23
25
  }
24
26
  export declare function resolveRequestedDeviceId(options: ScrcpyConnectDeviceRequest | undefined, currentDeviceId: string | null): string | undefined;
@@ -31,6 +33,7 @@ export default class ScrcpyServer {
31
33
  adbClient: AdbServerClient | null;
32
34
  currentDeviceId: string | null;
33
35
  devicePollInterval: NodeJS.Timeout | null;
36
+ readonly host: string;
34
37
  private deviceListSource?;
35
38
  private deviceListSourceUnsubscribe?;
36
39
  lastDeviceList: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/android-playground",
3
- "version": "1.12.4",
3
+ "version": "1.12.5-beta-20260907092148.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/web-infra-dev/midscene.git",
@@ -39,10 +39,10 @@
39
39
  "express": "^4.21.2",
40
40
  "open": "10.1.0",
41
41
  "socket.io": "^4.8.1",
42
- "@midscene/android": "1.12.4",
43
- "@midscene/playground": "1.12.4",
44
- "@midscene/core": "1.12.4",
45
- "@midscene/shared": "1.12.4"
42
+ "@midscene/android": "1.12.5-beta-20260907092148.0",
43
+ "@midscene/core": "1.12.5-beta-20260907092148.0",
44
+ "@midscene/playground": "1.12.5-beta-20260907092148.0",
45
+ "@midscene/shared": "1.12.5-beta-20260907092148.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@rslib/core": "^0.18.3",
package/static/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html><head><title>Midscene Android Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.574e3de9.js"></script><script defer src="/static/js/415.dadb20cf.js"></script><script defer src="/static/js/index.0769c3b5.js"></script><link href="/static/css/index.67caac18.css" rel="stylesheet"></head><body><div id="root"></div></body></html>
1
+ <!doctype html><html><head><title>Midscene Android Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.574e3de9.js"></script><script defer src="/static/js/415.dadb20cf.js"></script><script defer src="/static/js/index.fc4360f7.js"></script><link href="/static/css/index.67caac18.css" rel="stylesheet"></head><body><div id="root"></div></body></html>