@yume-chan/adb 1.0.0 → 2.0.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 (217) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +1 -1
  3. package/esm/adb.d.ts +7 -6
  4. package/esm/adb.d.ts.map +1 -1
  5. package/esm/adb.js +22 -22
  6. package/esm/adb.js.map +1 -1
  7. package/esm/banner.js.map +1 -1
  8. package/esm/commands/base.d.ts +3 -2
  9. package/esm/commands/base.d.ts.map +1 -1
  10. package/esm/commands/base.js +6 -3
  11. package/esm/commands/base.js.map +1 -1
  12. package/esm/commands/framebuffer.d.ts +6 -6
  13. package/esm/commands/power.d.ts +2 -2
  14. package/esm/commands/power.d.ts.map +1 -1
  15. package/esm/commands/power.js +4 -4
  16. package/esm/commands/power.js.map +1 -1
  17. package/esm/commands/reverse.d.ts +3 -4
  18. package/esm/commands/reverse.d.ts.map +1 -1
  19. package/esm/commands/reverse.js +5 -10
  20. package/esm/commands/reverse.js.map +1 -1
  21. package/esm/commands/subprocess/index.d.ts +3 -2
  22. package/esm/commands/subprocess/index.d.ts.map +1 -1
  23. package/esm/commands/subprocess/index.js +3 -2
  24. package/esm/commands/subprocess/index.js.map +1 -1
  25. package/esm/commands/subprocess/none/index.d.ts +5 -0
  26. package/esm/commands/subprocess/none/index.d.ts.map +1 -0
  27. package/esm/commands/subprocess/none/index.js +5 -0
  28. package/esm/commands/subprocess/none/index.js.map +1 -0
  29. package/esm/commands/subprocess/none/process.d.ts +13 -0
  30. package/esm/commands/subprocess/none/process.d.ts.map +1 -0
  31. package/esm/commands/subprocess/none/process.js +36 -0
  32. package/esm/commands/subprocess/none/process.js.map +1 -0
  33. package/esm/commands/subprocess/none/pty.d.ts +15 -0
  34. package/esm/commands/subprocess/none/pty.d.ts.map +1 -0
  35. package/esm/commands/subprocess/none/pty.js +29 -0
  36. package/esm/commands/subprocess/none/pty.js.map +1 -0
  37. package/esm/commands/subprocess/none/service.d.ts +10 -0
  38. package/esm/commands/subprocess/none/service.d.ts.map +1 -0
  39. package/esm/commands/subprocess/none/service.js +32 -0
  40. package/esm/commands/subprocess/none/service.js.map +1 -0
  41. package/esm/commands/subprocess/none/spawner.d.ts +19 -0
  42. package/esm/commands/subprocess/none/spawner.d.ts.map +1 -0
  43. package/esm/commands/subprocess/none/spawner.js +26 -0
  44. package/esm/commands/subprocess/none/spawner.js.map +1 -0
  45. package/esm/commands/subprocess/pty.d.ts +10 -0
  46. package/esm/commands/subprocess/pty.d.ts.map +1 -0
  47. package/esm/commands/subprocess/pty.js +2 -0
  48. package/esm/commands/subprocess/pty.js.map +1 -0
  49. package/esm/commands/subprocess/service.d.ts +11 -0
  50. package/esm/commands/subprocess/service.d.ts.map +1 -0
  51. package/esm/commands/subprocess/service.js +25 -0
  52. package/esm/commands/subprocess/service.js.map +1 -0
  53. package/esm/commands/subprocess/shell/index.d.ts +6 -0
  54. package/esm/commands/subprocess/shell/index.d.ts.map +1 -0
  55. package/esm/commands/subprocess/shell/index.js +6 -0
  56. package/esm/commands/subprocess/shell/index.js.map +1 -0
  57. package/esm/commands/subprocess/shell/process.d.ts +15 -0
  58. package/esm/commands/subprocess/shell/process.d.ts.map +1 -0
  59. package/esm/commands/subprocess/{protocols/shell.js → shell/process.js} +27 -54
  60. package/esm/commands/subprocess/shell/process.js.map +1 -0
  61. package/esm/commands/subprocess/shell/pty.d.ts +15 -0
  62. package/esm/commands/subprocess/shell/pty.d.ts.map +1 -0
  63. package/esm/commands/subprocess/shell/pty.js +76 -0
  64. package/esm/commands/subprocess/shell/pty.js.map +1 -0
  65. package/esm/commands/subprocess/shell/service.d.ts +14 -0
  66. package/esm/commands/subprocess/shell/service.d.ts.map +1 -0
  67. package/esm/commands/subprocess/shell/service.js +41 -0
  68. package/esm/commands/subprocess/shell/service.js.map +1 -0
  69. package/esm/commands/subprocess/shell/shared.d.ts +19 -0
  70. package/esm/commands/subprocess/shell/shared.d.ts.map +1 -0
  71. package/esm/commands/subprocess/shell/shared.js +15 -0
  72. package/esm/commands/subprocess/shell/shared.js.map +1 -0
  73. package/esm/commands/subprocess/shell/spawner.d.ts +24 -0
  74. package/esm/commands/subprocess/shell/spawner.d.ts.map +1 -0
  75. package/esm/commands/subprocess/shell/spawner.js +38 -0
  76. package/esm/commands/subprocess/shell/spawner.js.map +1 -0
  77. package/esm/commands/subprocess/utils.d.ts +1 -0
  78. package/esm/commands/subprocess/utils.d.ts.map +1 -1
  79. package/esm/commands/subprocess/utils.js +37 -0
  80. package/esm/commands/subprocess/utils.js.map +1 -1
  81. package/esm/commands/sync/list.d.ts +12 -8
  82. package/esm/commands/sync/list.d.ts.map +1 -1
  83. package/esm/commands/sync/list.js +5 -7
  84. package/esm/commands/sync/list.js.map +1 -1
  85. package/esm/commands/sync/pull.d.ts +4 -4
  86. package/esm/commands/sync/pull.d.ts.map +1 -1
  87. package/esm/commands/sync/pull.js +2 -7
  88. package/esm/commands/sync/pull.js.map +1 -1
  89. package/esm/commands/sync/push.d.ts +4 -4
  90. package/esm/commands/sync/request.d.ts +1 -1
  91. package/esm/commands/sync/response.d.ts +5 -5
  92. package/esm/commands/sync/response.d.ts.map +1 -1
  93. package/esm/commands/sync/response.js +2 -1
  94. package/esm/commands/sync/response.js.map +1 -1
  95. package/esm/commands/sync/stat.d.ts +4 -4
  96. package/esm/commands/sync/sync.d.ts +2 -2
  97. package/esm/commands/sync/sync.js +1 -1
  98. package/esm/commands/sync/sync.js.map +1 -1
  99. package/esm/commands/tcpip.d.ts +2 -2
  100. package/esm/commands/tcpip.js +2 -2
  101. package/esm/daemon/dispatcher.d.ts.map +1 -1
  102. package/esm/daemon/dispatcher.js.map +1 -1
  103. package/esm/daemon/packet.d.ts +6 -4
  104. package/esm/daemon/packet.d.ts.map +1 -1
  105. package/esm/daemon/packet.js +3 -5
  106. package/esm/daemon/packet.js.map +1 -1
  107. package/esm/daemon/socket.d.ts +2 -2
  108. package/esm/daemon/socket.d.ts.map +1 -1
  109. package/esm/daemon/socket.js +1 -1
  110. package/esm/daemon/socket.js.map +1 -1
  111. package/esm/device-observer.d.ts +4 -4
  112. package/esm/device-observer.d.ts.map +1 -1
  113. package/esm/server/client.d.ts +15 -57
  114. package/esm/server/client.d.ts.map +1 -1
  115. package/esm/server/client.js +66 -263
  116. package/esm/server/client.js.map +1 -1
  117. package/esm/server/commands/index.d.ts +3 -0
  118. package/esm/server/commands/index.d.ts.map +1 -0
  119. package/esm/server/commands/index.js +3 -0
  120. package/esm/server/commands/index.js.map +1 -0
  121. package/esm/server/commands/m-dns.d.ts +12 -0
  122. package/esm/server/commands/m-dns.d.ts.map +1 -0
  123. package/esm/server/commands/m-dns.js +38 -0
  124. package/esm/server/commands/m-dns.js.map +1 -0
  125. package/esm/server/commands/wireless.d.ts +27 -0
  126. package/esm/server/commands/wireless.d.ts.map +1 -0
  127. package/esm/server/commands/wireless.js +82 -0
  128. package/esm/server/commands/wireless.js.map +1 -0
  129. package/esm/server/index.d.ts +2 -0
  130. package/esm/server/index.d.ts.map +1 -1
  131. package/esm/server/index.js +2 -0
  132. package/esm/server/index.js.map +1 -1
  133. package/esm/server/observer.d.ts +9 -0
  134. package/esm/server/observer.d.ts.map +1 -0
  135. package/esm/server/observer.js +128 -0
  136. package/esm/server/observer.js.map +1 -0
  137. package/esm/server/stream.d.ts +19 -0
  138. package/esm/server/stream.d.ts.map +1 -0
  139. package/esm/server/stream.js +77 -0
  140. package/esm/server/stream.js.map +1 -0
  141. package/esm/server/transport.d.ts +3 -4
  142. package/esm/server/transport.d.ts.map +1 -1
  143. package/esm/server/transport.js +18 -16
  144. package/esm/server/transport.js.map +1 -1
  145. package/esm/utils/index.d.ts +1 -0
  146. package/esm/utils/index.d.ts.map +1 -1
  147. package/esm/utils/index.js +1 -0
  148. package/esm/utils/index.js.map +1 -1
  149. package/esm/utils/ref.d.ts +18 -0
  150. package/esm/utils/ref.d.ts.map +1 -0
  151. package/esm/utils/ref.js +29 -0
  152. package/esm/utils/ref.js.map +1 -0
  153. package/package.json +10 -10
  154. package/src/adb.ts +29 -28
  155. package/src/banner.ts +4 -4
  156. package/src/commands/base.ts +6 -3
  157. package/src/commands/power.ts +6 -6
  158. package/src/commands/reverse.ts +9 -12
  159. package/src/commands/subprocess/index.ts +3 -2
  160. package/src/commands/subprocess/none/index.ts +4 -0
  161. package/src/commands/subprocess/none/process.ts +56 -0
  162. package/src/commands/subprocess/none/pty.ts +45 -0
  163. package/src/commands/subprocess/none/service.ts +42 -0
  164. package/src/commands/subprocess/none/spawner.ts +68 -0
  165. package/src/commands/subprocess/pty.ts +15 -0
  166. package/src/commands/subprocess/service.ts +32 -0
  167. package/src/commands/subprocess/shell/index.ts +5 -0
  168. package/src/commands/subprocess/shell/process.ts +127 -0
  169. package/src/commands/subprocess/shell/pty.ts +112 -0
  170. package/src/commands/subprocess/shell/service.ts +58 -0
  171. package/src/commands/subprocess/shell/shared.ts +25 -0
  172. package/src/commands/subprocess/shell/spawner.ts +90 -0
  173. package/src/commands/subprocess/utils.ts +41 -0
  174. package/src/commands/sync/list.ts +7 -17
  175. package/src/commands/sync/pull.ts +2 -8
  176. package/src/commands/sync/response.ts +6 -4
  177. package/src/commands/sync/sync.ts +1 -1
  178. package/src/commands/tcpip.ts +2 -2
  179. package/src/daemon/dispatcher.ts +7 -4
  180. package/src/daemon/packet.ts +4 -8
  181. package/src/daemon/socket.ts +6 -6
  182. package/src/device-observer.ts +4 -4
  183. package/src/server/client.ts +100 -305
  184. package/src/server/commands/index.ts +2 -0
  185. package/src/server/commands/m-dns.ts +43 -0
  186. package/src/server/commands/wireless.ts +94 -0
  187. package/src/server/index.ts +2 -0
  188. package/src/server/observer.ts +172 -0
  189. package/src/server/stream.ts +100 -0
  190. package/src/server/transport.ts +38 -34
  191. package/src/utils/index.ts +1 -0
  192. package/src/utils/ref.ts +37 -0
  193. package/tsconfig.build.tsbuildinfo +1 -1
  194. package/esm/commands/subprocess/command.d.ts +0 -58
  195. package/esm/commands/subprocess/command.d.ts.map +0 -1
  196. package/esm/commands/subprocess/command.js +0 -89
  197. package/esm/commands/subprocess/command.js.map +0 -1
  198. package/esm/commands/subprocess/protocols/index.d.ts +0 -4
  199. package/esm/commands/subprocess/protocols/index.d.ts.map +0 -1
  200. package/esm/commands/subprocess/protocols/index.js +0 -4
  201. package/esm/commands/subprocess/protocols/index.js.map +0 -1
  202. package/esm/commands/subprocess/protocols/none.d.ts +0 -32
  203. package/esm/commands/subprocess/protocols/none.d.ts.map +0 -1
  204. package/esm/commands/subprocess/protocols/none.js +0 -61
  205. package/esm/commands/subprocess/protocols/none.js.map +0 -1
  206. package/esm/commands/subprocess/protocols/shell.d.ts +0 -42
  207. package/esm/commands/subprocess/protocols/shell.d.ts.map +0 -1
  208. package/esm/commands/subprocess/protocols/shell.js.map +0 -1
  209. package/esm/commands/subprocess/protocols/types.d.ts +0 -49
  210. package/esm/commands/subprocess/protocols/types.d.ts.map +0 -1
  211. package/esm/commands/subprocess/protocols/types.js +0 -2
  212. package/esm/commands/subprocess/protocols/types.js.map +0 -1
  213. package/src/commands/subprocess/command.ts +0 -141
  214. package/src/commands/subprocess/protocols/index.ts +0 -3
  215. package/src/commands/subprocess/protocols/none.ts +0 -81
  216. package/src/commands/subprocess/protocols/shell.ts +0 -171
  217. package/src/commands/subprocess/protocols/types.ts +0 -63
@@ -1,7 +1,6 @@
1
1
  import { PromiseResolver } from "@yume-chan/async";
2
- import { AbortController } from "@yume-chan/stream-extra";
3
2
  import { AdbFeature } from "../features.js";
4
- export const ADB_SERVER_DEFAULT_FEATURES = [
3
+ export const ADB_SERVER_DEFAULT_FEATURES = /* #__PURE__ */ (() => [
5
4
  AdbFeature.ShellV2,
6
5
  AdbFeature.Cmd,
7
6
  AdbFeature.StatV2,
@@ -20,36 +19,36 @@ export const ADB_SERVER_DEFAULT_FEATURES = [
20
19
  "sendrecv_v2_lz4",
21
20
  "sendrecv_v2_zstd",
22
21
  "sendrecv_v2_dry_run_send",
23
- ];
22
+ ])();
24
23
  export class AdbServerTransport {
25
24
  #client;
26
25
  serial;
27
26
  transportId;
28
27
  maxPayloadSize = 1 * 1024 * 1024;
29
28
  banner;
29
+ #sockets = [];
30
30
  #closed = new PromiseResolver();
31
- #waitAbortController = new AbortController();
32
- disconnected;
31
+ #disconnected;
32
+ get disconnected() {
33
+ return this.#disconnected;
34
+ }
33
35
  get clientFeatures() {
34
36
  // No need to get host features (features supported by ADB server)
35
37
  // Because we create all ADB packets ourselves
36
38
  return ADB_SERVER_DEFAULT_FEATURES;
37
39
  }
38
- constructor(client, serial, banner, transportId) {
40
+ // eslint-disable-next-line @typescript-eslint/max-params
41
+ constructor(client, serial, banner, transportId, disconnected) {
39
42
  this.#client = client;
40
43
  this.serial = serial;
41
44
  this.banner = banner;
42
45
  this.transportId = transportId;
43
- this.disconnected = Promise.race([
44
- this.#closed.promise,
45
- client.waitFor({ transportId }, "disconnect", {
46
- signal: this.#waitAbortController.signal,
47
- unref: true,
48
- }),
49
- ]);
46
+ this.#disconnected = Promise.race([this.#closed.promise, disconnected]);
50
47
  }
51
48
  async connect(service) {
52
- return await this.#client.createDeviceConnection({ transportId: this.transportId }, service);
49
+ const socket = await this.#client.createDeviceConnection({ transportId: this.transportId }, service);
50
+ this.#sockets.push(socket);
51
+ return socket;
53
52
  }
54
53
  async addReverseTunnel(handler, address) {
55
54
  return await this.#client.connector.addReverseTunnel(handler, address);
@@ -60,9 +59,12 @@ export class AdbServerTransport {
60
59
  async clearReverseTunnels() {
61
60
  await this.#client.connector.clearReverseTunnels();
62
61
  }
63
- close() {
62
+ async close() {
63
+ for (const socket of this.#sockets) {
64
+ await socket.close();
65
+ }
66
+ this.#sockets.length = 0;
64
67
  this.#closed.resolve();
65
- this.#waitAbortController.abort();
66
68
  }
67
69
  }
68
70
  //# sourceMappingURL=transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/server/transport.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAQ1D,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACvC,UAAU,CAAC,OAAO;IAClB,UAAU,CAAC,GAAG;IACd,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,cAAc;IACzB,MAAM;IACN,UAAU,CAAC,GAAG;IACd,yFAAyF;IACzF,gCAAgC;IAChC,8BAA8B;IAC9B,UAAU,CAAC,OAAO;IAClB,eAAe;IACf,WAAW;IACX,UAAU,CAAC,aAAa;IACxB,oBAAoB;IACpB,iBAAiB;IACjB,kBAAkB;IAClB,0BAA0B;CACb,CAAC;AAElB,MAAM,OAAO,kBAAkB;IAC3B,OAAO,CAAkB;IAEhB,MAAM,CAAS;IAEf,WAAW,CAAS;IAEpB,cAAc,GAAW,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAEzC,MAAM,CAAY;IAE3B,OAAO,GAAG,IAAI,eAAe,EAAQ,CAAC;IACtC,oBAAoB,GAAG,IAAI,eAAe,EAAE,CAAC;IACpC,YAAY,CAAgB;IAErC,IAAI,cAAc;QACd,kEAAkE;QAClE,8CAA8C;QAC9C,OAAO,2BAA2B,CAAC;IACvC,CAAC;IAED,YACI,MAAuB,EACvB,MAAc,EACd,MAAiB,EACjB,WAAmB;QAEnB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE/B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,OAAO;YACpB,MAAM,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE;gBAC1C,MAAM,EAAE,IAAI,CAAC,oBAAoB,CAAC,MAAM;gBACxC,KAAK,EAAE,IAAI;aACd,CAAC;SACL,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe;QACzB,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAC5C,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EACjC,OAAO,CACV,CAAC;IACN,CAAC;IAED,KAAK,CAAC,gBAAgB,CAClB,OAAiC,EACjC,OAAgB;QAEhB,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,OAAe;QACrC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,mBAAmB;QACrB,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IACvD,CAAC;IAED,KAAK;QACD,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC;IACtC,CAAC;CACJ"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/server/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAQnD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAI5C,MAAM,CAAC,MAAM,2BAA2B,GAAG,eAAe,CAAC,CAAC,GAAG,EAAE,CAC7D;IACI,UAAU,CAAC,OAAO;IAClB,UAAU,CAAC,GAAG;IACd,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,MAAM;IACjB,UAAU,CAAC,cAAc;IACzB,MAAM;IACN,UAAU,CAAC,GAAG;IACd,yFAAyF;IACzF,gCAAgC;IAChC,8BAA8B;IAC9B,UAAU,CAAC,OAAO;IAClB,eAAe;IACf,WAAW;IACX,UAAU,CAAC,aAAa;IACxB,oBAAoB;IACpB,iBAAiB;IACjB,kBAAkB;IAClB,0BAA0B;CACb,CAAC,EAAE,CAAC;AAEzB,MAAM,OAAO,kBAAkB;IAC3B,OAAO,CAAkB;IAEhB,MAAM,CAAS;IAEf,WAAW,CAAS;IAEpB,cAAc,GAAW,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAEzC,MAAM,CAAY;IAE3B,QAAQ,GAAgB,EAAE,CAAC;IAE3B,OAAO,GAAG,IAAI,eAAe,EAAQ,CAAC;IACtC,aAAa,CAAgB;IAC7B,IAAI,YAAY;QACZ,OAAO,IAAI,CAAC,aAAa,CAAC;IAC9B,CAAC;IAED,IAAI,cAAc;QACd,kEAAkE;QAClE,8CAA8C;QAC9C,OAAO,2BAA2B,CAAC;IACvC,CAAC;IAED,yDAAyD;IACzD,YACI,MAAuB,EACvB,MAAc,EACd,MAAiB,EACjB,WAAmB,EACnB,YAA2B;QAE3B,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAE/B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAC5E,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAe;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,sBAAsB,CACpD,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,EACjC,OAAO,CACV,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAClB,OAAiC,EACjC,OAAgB;QAEhB,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,OAAe;QACrC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,mBAAmB;QACrB,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,KAAK;QACP,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACjC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAC3B,CAAC;CACJ"}
@@ -3,5 +3,6 @@ export * from "./auto-reset-event.js";
3
3
  export * from "./base64.js";
4
4
  export * from "./hex.js";
5
5
  export * from "./no-op.js";
6
+ export * from "./ref.js";
6
7
  export * from "./sequence-equal.js";
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC"}
@@ -3,5 +3,6 @@ export * from "./auto-reset-event.js";
3
3
  export * from "./base64.js";
4
4
  export * from "./hex.js";
5
5
  export * from "./no-op.js";
6
+ export * from "./ref.js";
6
7
  export * from "./sequence-equal.js";
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC3D,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * An object to keep current Node.js process alive even when no code is running.
3
+ *
4
+ * Does nothing in Web environments.
5
+ *
6
+ * Note that it does't have reference counting. Calling `unref` will
7
+ * remove the ref no matter how many times `ref` has been previously called, and vice versa.
8
+ * This is the same as how Node.js works.
9
+ */
10
+ export declare class Ref {
11
+ #private;
12
+ constructor(options?: {
13
+ unref?: boolean | undefined;
14
+ });
15
+ ref(): void;
16
+ unref(): void;
17
+ }
18
+ //# sourceMappingURL=ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.d.ts","sourceRoot":"","sources":["../../src/utils/ref.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,qBAAa,GAAG;;gBAGA,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE;IAMrD,GAAG;IAKH,KAAK;CAMR"}
@@ -0,0 +1,29 @@
1
+ const { setInterval, clearInterval } = globalThis;
2
+ /**
3
+ * An object to keep current Node.js process alive even when no code is running.
4
+ *
5
+ * Does nothing in Web environments.
6
+ *
7
+ * Note that it does't have reference counting. Calling `unref` will
8
+ * remove the ref no matter how many times `ref` has been previously called, and vice versa.
9
+ * This is the same as how Node.js works.
10
+ */
11
+ export class Ref {
12
+ #intervalId;
13
+ constructor(options) {
14
+ if (!options?.unref) {
15
+ this.ref();
16
+ }
17
+ }
18
+ ref() {
19
+ // `setInterval` can keep current Node.js alive, the delay value doesn't matter
20
+ this.#intervalId = setInterval(() => { }, 60 * 1000);
21
+ }
22
+ unref() {
23
+ if (this.#intervalId) {
24
+ clearInterval(this.#intervalId);
25
+ this.#intervalId = undefined;
26
+ }
27
+ }
28
+ }
29
+ //# sourceMappingURL=ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ref.js","sourceRoot":"","sources":["../../src/utils/ref.ts"],"names":[],"mappings":"AAKA,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,UAAwC,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,OAAO,GAAG;IACZ,WAAW,CAAqB;IAEhC,YAAY,OAAyC;QACjD,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;IACL,CAAC;IAED,GAAG;QACC,+EAA+E;QAC/E,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,GAAE,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACxD,CAAC;IAED,KAAK;QACD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAChC,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QACjC,CAAC;IACL,CAAC;CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yume-chan/adb",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "TypeScript implementation of Android Debug Bridge (ADB) protocol.",
5
5
  "keywords": [
6
6
  "adb",
@@ -27,18 +27,18 @@
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
29
  "@yume-chan/async": "^4.0.2",
30
- "@yume-chan/event": "^1.0.0",
31
- "@yume-chan/stream-extra": "^1.0.0",
32
- "@yume-chan/struct": "^1.0.0",
33
- "@yume-chan/no-data-view": "^1.0.0"
30
+ "@yume-chan/event": "^2.0.0",
31
+ "@yume-chan/stream-extra": "^2.0.0",
32
+ "@yume-chan/no-data-view": "^2.0.0",
33
+ "@yume-chan/struct": "^2.0.0"
34
34
  },
35
35
  "devDependencies": {
36
- "@types/node": "^22.10.0",
37
- "prettier": "^3.4.1",
38
- "typescript": "^5.7.2",
36
+ "@types/node": "^22.13.10",
37
+ "prettier": "^3.5.3",
38
+ "typescript": "^5.8.2",
39
39
  "@yume-chan/eslint-config": "^1.0.0",
40
- "@yume-chan/test-runner": "^1.0.0",
41
- "@yume-chan/tsconfig": "^1.0.0"
40
+ "@yume-chan/tsconfig": "^1.0.0",
41
+ "@yume-chan/test-runner": "^1.0.0"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc -b tsconfig.build.json",
package/src/adb.ts CHANGED
@@ -9,10 +9,10 @@ import type { AdbBanner } from "./banner.js";
9
9
  import type { AdbFrameBuffer } from "./commands/index.js";
10
10
  import {
11
11
  AdbPower,
12
- AdbReverseCommand,
13
- AdbSubprocess,
12
+ AdbReverseService,
13
+ AdbSubprocessService,
14
14
  AdbSync,
15
- AdbTcpIpCommand,
15
+ AdbTcpIpService,
16
16
  escapeArg,
17
17
  framebuffer,
18
18
  } from "./commands/index.js";
@@ -30,7 +30,7 @@ export interface AdbSocket
30
30
  Closeable {
31
31
  get service(): string;
32
32
 
33
- get closed(): Promise<void>;
33
+ get closed(): Promise<undefined>;
34
34
  }
35
35
 
36
36
  export type AdbIncomingSocketHandler = (
@@ -61,44 +61,47 @@ export interface AdbTransport extends Closeable {
61
61
  }
62
62
 
63
63
  export class Adb implements Closeable {
64
- readonly transport: AdbTransport;
64
+ readonly #transport: AdbTransport;
65
+ get transport(): AdbTransport {
66
+ return this.#transport;
67
+ }
65
68
 
66
69
  get serial() {
67
- return this.transport.serial;
70
+ return this.#transport.serial;
68
71
  }
69
72
 
70
73
  get maxPayloadSize() {
71
- return this.transport.maxPayloadSize;
74
+ return this.#transport.maxPayloadSize;
72
75
  }
73
76
 
74
77
  get banner() {
75
- return this.transport.banner;
78
+ return this.#transport.banner;
76
79
  }
77
80
 
78
81
  get disconnected() {
79
- return this.transport.disconnected;
82
+ return this.#transport.disconnected;
80
83
  }
81
84
 
82
85
  public get clientFeatures() {
83
- return this.transport.clientFeatures;
86
+ return this.#transport.clientFeatures;
84
87
  }
85
88
 
86
89
  public get deviceFeatures() {
87
90
  return this.banner.features;
88
91
  }
89
92
 
90
- readonly subprocess: AdbSubprocess;
93
+ readonly subprocess: AdbSubprocessService;
91
94
  readonly power: AdbPower;
92
- readonly reverse: AdbReverseCommand;
93
- readonly tcpip: AdbTcpIpCommand;
95
+ readonly reverse: AdbReverseService;
96
+ readonly tcpip: AdbTcpIpService;
94
97
 
95
98
  constructor(transport: AdbTransport) {
96
- this.transport = transport;
99
+ this.#transport = transport;
97
100
 
98
- this.subprocess = new AdbSubprocess(this);
101
+ this.subprocess = new AdbSubprocessService(this);
99
102
  this.power = new AdbPower(this);
100
- this.reverse = new AdbReverseCommand(this);
101
- this.tcpip = new AdbTcpIpCommand(this);
103
+ this.reverse = new AdbReverseService(this);
104
+ this.tcpip = new AdbTcpIpService(this);
102
105
  }
103
106
 
104
107
  canUseFeature(feature: AdbFeature): boolean {
@@ -112,7 +115,7 @@ export class Adb implements Closeable {
112
115
  * Creates a new ADB Socket to the specified service or socket address.
113
116
  */
114
117
  async createSocket(service: string): Promise<AdbSocket> {
115
- return this.transport.connect(service);
118
+ return this.#transport.connect(service);
116
119
  }
117
120
 
118
121
  async createSocketAndWait(service: string): Promise<string> {
@@ -122,15 +125,13 @@ export class Adb implements Closeable {
122
125
  .pipeThrough(new ConcatStringStream());
123
126
  }
124
127
 
125
- async getProp(key: string): Promise<string> {
126
- const stdout = await this.subprocess.spawnAndWaitLegacy([
127
- "getprop",
128
- key,
129
- ]);
130
- return stdout.trim();
128
+ getProp(key: string): Promise<string> {
129
+ return this.subprocess.noneProtocol
130
+ .spawnWaitText(["getprop", key])
131
+ .then((output) => output.trim());
131
132
  }
132
133
 
133
- async rm(
134
+ rm(
134
135
  filenames: string | string[],
135
136
  options?: { recursive?: boolean; force?: boolean },
136
137
  ): Promise<string> {
@@ -150,8 +151,8 @@ export class Adb implements Closeable {
150
151
  }
151
152
  // https://android.googlesource.com/platform/packages/modules/adb/+/1a0fb8846d4e6b671c8aa7f137a8c21d7b248716/client/adb_install.cpp#984
152
153
  args.push("</dev/null");
153
- const stdout = await this.subprocess.spawnAndWaitLegacy(args);
154
- return stdout;
154
+
155
+ return this.subprocess.noneProtocol.spawnWaitText(args);
155
156
  }
156
157
 
157
158
  async sync(): Promise<AdbSync> {
@@ -164,6 +165,6 @@ export class Adb implements Closeable {
164
165
  }
165
166
 
166
167
  async close(): Promise<void> {
167
- await this.transport.close();
168
+ await this.#transport.close();
168
169
  }
169
170
  }
package/src/banner.ts CHANGED
@@ -51,22 +51,22 @@ export class AdbBanner {
51
51
  return new AdbBanner(product, model, device, features);
52
52
  }
53
53
 
54
- #product: string | undefined;
54
+ readonly #product: string | undefined;
55
55
  get product() {
56
56
  return this.#product;
57
57
  }
58
58
 
59
- #model: string | undefined;
59
+ readonly #model: string | undefined;
60
60
  get model() {
61
61
  return this.#model;
62
62
  }
63
63
 
64
- #device: string | undefined;
64
+ readonly #device: string | undefined;
65
65
  get device() {
66
66
  return this.#device;
67
67
  }
68
68
 
69
- #features: AdbFeature[] = [];
69
+ readonly #features: AdbFeature[] = [];
70
70
  get features() {
71
71
  return this.#features;
72
72
  }
@@ -2,11 +2,14 @@ import { AutoDisposable } from "@yume-chan/event";
2
2
 
3
3
  import type { Adb } from "../adb.js";
4
4
 
5
- export class AdbCommandBase extends AutoDisposable {
6
- protected adb: Adb;
5
+ export class AdbServiceBase extends AutoDisposable {
6
+ readonly #adb: Adb;
7
+ get adb() {
8
+ return this.#adb;
9
+ }
7
10
 
8
11
  constructor(adb: Adb) {
9
12
  super();
10
- this.adb = adb;
13
+ this.#adb = adb;
11
14
  }
12
15
  }
@@ -3,9 +3,9 @@
3
3
  // cspell: ignore keyevent
4
4
  // cspell: ignore longpress
5
5
 
6
- import { AdbCommandBase } from "./base.js";
6
+ import { AdbServiceBase } from "./base.js";
7
7
 
8
- export class AdbPower extends AdbCommandBase {
8
+ export class AdbPower extends AdbServiceBase {
9
9
  reboot(mode = "") {
10
10
  return this.adb.createSocketAndWait(`reboot:${mode}`);
11
11
  }
@@ -35,18 +35,18 @@ export class AdbPower extends AdbCommandBase {
35
35
  return this.reboot("edl");
36
36
  }
37
37
 
38
- powerOff() {
39
- return this.adb.subprocess.spawnAndWaitLegacy(["reboot", "-p"]);
38
+ powerOff(): Promise<string> {
39
+ return this.adb.subprocess.noneProtocol.spawnWaitText(["reboot", "-p"]);
40
40
  }
41
41
 
42
- powerButton(longPress = false) {
42
+ powerButton(longPress = false): Promise<string> {
43
43
  const args = ["input", "keyevent"];
44
44
  if (longPress) {
45
45
  args.push("--longpress");
46
46
  }
47
47
  args.push("POWER");
48
48
 
49
- return this.adb.subprocess.spawnAndWaitLegacy(args);
49
+ return this.adb.subprocess.noneProtocol.spawnWaitText(args);
50
50
  }
51
51
 
52
52
  /**
@@ -4,13 +4,16 @@ import { BufferedReadableStream } from "@yume-chan/stream-extra";
4
4
  import {
5
5
  encodeUtf8,
6
6
  ExactReadableEndedError,
7
+ extend,
7
8
  string,
8
9
  struct,
9
10
  } from "@yume-chan/struct";
10
11
 
11
- import type { Adb, AdbIncomingSocketHandler } from "../adb.js";
12
+ import type { AdbIncomingSocketHandler } from "../adb.js";
12
13
  import { hexToNumber, sequenceEqual } from "../utils/index.js";
13
14
 
15
+ import { AdbServiceBase } from "./base.js";
16
+
14
17
  export interface AdbForwardListener {
15
18
  deviceSerial: string;
16
19
 
@@ -49,11 +52,11 @@ export class AdbReverseNotSupportedError extends AdbReverseError {
49
52
  }
50
53
  }
51
54
 
52
- const AdbReverseErrorResponse = struct(
53
- /* #__PURE__ */ (() => AdbReverseStringResponse.fields)(),
55
+ const AdbReverseErrorResponse = extend(
56
+ AdbReverseStringResponse,
57
+ {},
54
58
  {
55
- littleEndian: true,
56
- postDeserialize: (value) => {
59
+ postDeserialize(value) {
57
60
  // https://issuetracker.google.com/issues/37066218
58
61
  // ADB on Android <9 can't create reverse tunnels when connected wirelessly (ADB over Wi-Fi),
59
62
  // and returns this confusing "more than one device/emulator" error.
@@ -81,15 +84,9 @@ function decimalToNumber(buffer: Uint8Array) {
81
84
 
82
85
  const OKAY = encodeUtf8("OKAY");
83
86
 
84
- export class AdbReverseCommand {
85
- protected adb: Adb;
86
-
87
+ export class AdbReverseService extends AdbServiceBase {
87
88
  readonly #deviceAddressToLocalAddress = new Map<string, string>();
88
89
 
89
- constructor(adb: Adb) {
90
- this.adb = adb;
91
- }
92
-
93
90
  protected async createBufferedStream(service: string) {
94
91
  const socket = await this.adb.createSocket(service);
95
92
  return new BufferedReadableStream(socket.readable);
@@ -1,3 +1,4 @@
1
- export * from "./command.js";
2
- export * from "./protocols/index.js";
1
+ export * from "./none/index.js";
2
+ export * from "./service.js";
3
+ export * from "./shell/index.js";
3
4
  export * from "./utils.js";
@@ -0,0 +1,4 @@
1
+ export * from "./process.js";
2
+ export * from "./pty.js";
3
+ export * from "./service.js";
4
+ export * from "./spawner.js";
@@ -0,0 +1,56 @@
1
+ import type { MaybePromiseLike } from "@yume-chan/async";
2
+ import { PromiseResolver } from "@yume-chan/async";
3
+ import type {
4
+ AbortSignal,
5
+ MaybeConsumable,
6
+ ReadableStream,
7
+ WritableStream,
8
+ } from "@yume-chan/stream-extra";
9
+
10
+ import type { AdbSocket } from "../../../adb.js";
11
+
12
+ import type { AdbNoneProtocolProcess } from "./spawner.js";
13
+
14
+ export class AdbNoneProtocolProcessImpl implements AdbNoneProtocolProcess {
15
+ readonly #socket: AdbSocket;
16
+
17
+ get stdin(): WritableStream<MaybeConsumable<Uint8Array>> {
18
+ return this.#socket.writable;
19
+ }
20
+
21
+ get output(): ReadableStream<Uint8Array> {
22
+ return this.#socket.readable;
23
+ }
24
+
25
+ readonly #exited: Promise<undefined>;
26
+ get exited(): Promise<undefined> {
27
+ return this.#exited;
28
+ }
29
+
30
+ constructor(socket: AdbSocket, signal?: AbortSignal) {
31
+ this.#socket = socket;
32
+
33
+ if (signal) {
34
+ // `signal` won't affect `this.output`
35
+ // So remaining data can still be read
36
+ // (call `controller.error` will discard all pending data)
37
+
38
+ const exited = new PromiseResolver<undefined>();
39
+ this.#socket.closed.then(
40
+ () => exited.resolve(undefined),
41
+ (e) => exited.reject(e),
42
+ );
43
+ signal.addEventListener("abort", () => {
44
+ exited.reject(signal.reason);
45
+ this.#socket.close();
46
+ });
47
+ this.#exited = exited.promise;
48
+ } else {
49
+ this.#exited = this.#socket.closed;
50
+ }
51
+ }
52
+
53
+ kill(): MaybePromiseLike<void> {
54
+ return this.#socket.close();
55
+ }
56
+ }
@@ -0,0 +1,45 @@
1
+ import type { MaybePromiseLike } from "@yume-chan/async";
2
+ import type {
3
+ ReadableStream,
4
+ WritableStream,
5
+ WritableStreamDefaultWriter,
6
+ } from "@yume-chan/stream-extra";
7
+ import { MaybeConsumable } from "@yume-chan/stream-extra";
8
+
9
+ import type { AdbSocket } from "../../../adb.js";
10
+ import type { AdbPtyProcess } from "../pty.js";
11
+
12
+ export class AdbNoneProtocolPtyProcess implements AdbPtyProcess<undefined> {
13
+ readonly #socket: AdbSocket;
14
+ readonly #writer: WritableStreamDefaultWriter<MaybeConsumable<Uint8Array>>;
15
+
16
+ readonly #input: MaybeConsumable.WritableStream<Uint8Array>;
17
+ get input(): WritableStream<MaybeConsumable<Uint8Array>> {
18
+ return this.#input;
19
+ }
20
+
21
+ get output(): ReadableStream<Uint8Array> {
22
+ return this.#socket.readable;
23
+ }
24
+
25
+ get exited(): Promise<undefined> {
26
+ return this.#socket.closed;
27
+ }
28
+
29
+ constructor(socket: AdbSocket) {
30
+ this.#socket = socket;
31
+
32
+ this.#writer = this.#socket.writable.getWriter();
33
+ this.#input = new MaybeConsumable.WritableStream<Uint8Array>({
34
+ write: (chunk) => this.#writer.write(chunk),
35
+ });
36
+ }
37
+
38
+ sigint() {
39
+ return this.#writer.write(new Uint8Array([0x03]));
40
+ }
41
+
42
+ kill(): MaybePromiseLike<void> {
43
+ return this.#socket.close();
44
+ }
45
+ }
@@ -0,0 +1,42 @@
1
+ import type { Adb } from "../../../adb.js";
2
+
3
+ import { AdbNoneProtocolProcessImpl } from "./process.js";
4
+ import { AdbNoneProtocolPtyProcess } from "./pty.js";
5
+ import { AdbNoneProtocolSpawner } from "./spawner.js";
6
+
7
+ export class AdbNoneProtocolSubprocessService extends AdbNoneProtocolSpawner {
8
+ readonly #adb: Adb;
9
+ get adb(): Adb {
10
+ return this.#adb;
11
+ }
12
+
13
+ constructor(adb: Adb) {
14
+ super(async (command, signal) => {
15
+ // `shell,raw:${command}` also triggers raw mode,
16
+ // But is not supported on Android version <7.
17
+ const socket = await this.#adb.createSocket(
18
+ `exec:${command.join(" ")}`,
19
+ );
20
+
21
+ if (signal?.aborted) {
22
+ await socket.close();
23
+ throw signal.reason;
24
+ }
25
+
26
+ return new AdbNoneProtocolProcessImpl(socket, signal);
27
+ });
28
+ this.#adb = adb;
29
+ }
30
+
31
+ async pty(command?: string | string[]): Promise<AdbNoneProtocolPtyProcess> {
32
+ if (command === undefined) {
33
+ command = "";
34
+ } else if (Array.isArray(command)) {
35
+ command = command.join(" ");
36
+ }
37
+
38
+ return new AdbNoneProtocolPtyProcess(
39
+ await this.#adb.createSocket(`shell:${command}`),
40
+ );
41
+ }
42
+ }