@yume-chan/adb 0.0.19 → 0.0.20

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 (181) hide show
  1. package/CHANGELOG.json +33 -0
  2. package/CHANGELOG.md +15 -1
  3. package/README.md +220 -103
  4. package/esm/adb.d.ts +24 -44
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js +14 -203
  7. package/esm/adb.js.map +1 -1
  8. package/esm/banner.d.ts +17 -0
  9. package/esm/banner.d.ts.map +1 -0
  10. package/esm/banner.js +67 -0
  11. package/esm/banner.js.map +1 -0
  12. package/esm/commands/power.d.ts +1 -1
  13. package/esm/commands/power.js +2 -2
  14. package/esm/commands/reverse.d.ts +17 -18
  15. package/esm/commands/reverse.d.ts.map +1 -1
  16. package/esm/commands/reverse.js +53 -48
  17. package/esm/commands/reverse.js.map +1 -1
  18. package/esm/commands/subprocess/protocols/none.d.ts +3 -8
  19. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  20. package/esm/commands/subprocess/protocols/none.js +16 -16
  21. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  22. package/esm/commands/subprocess/protocols/shell.d.ts +3 -9
  23. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  24. package/esm/commands/subprocess/protocols/shell.js +48 -42
  25. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  26. package/esm/commands/subprocess/protocols/types.d.ts +1 -2
  27. package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
  28. package/esm/commands/sync/list.js +2 -2
  29. package/esm/commands/sync/push.d.ts +14 -3
  30. package/esm/commands/sync/push.d.ts.map +1 -1
  31. package/esm/commands/sync/push.js +8 -8
  32. package/esm/commands/sync/push.js.map +1 -1
  33. package/esm/commands/sync/request.js +1 -1
  34. package/esm/commands/sync/response.d.ts +3 -3
  35. package/esm/commands/sync/response.d.ts.map +1 -1
  36. package/esm/commands/sync/response.js +3 -3
  37. package/esm/commands/sync/response.js.map +1 -1
  38. package/esm/commands/sync/socket.d.ts +8 -13
  39. package/esm/commands/sync/socket.d.ts.map +1 -1
  40. package/esm/commands/sync/socket.js +32 -29
  41. package/esm/commands/sync/socket.js.map +1 -1
  42. package/esm/commands/sync/stat.js +2 -2
  43. package/esm/commands/sync/stat.js.map +1 -1
  44. package/esm/commands/sync/sync.d.ts +11 -18
  45. package/esm/commands/sync/sync.d.ts.map +1 -1
  46. package/esm/commands/sync/sync.js +19 -23
  47. package/esm/commands/sync/sync.js.map +1 -1
  48. package/esm/commands/tcpip.d.ts +2 -2
  49. package/esm/commands/tcpip.d.ts.map +1 -1
  50. package/esm/commands/tcpip.js +4 -2
  51. package/esm/commands/tcpip.js.map +1 -1
  52. package/esm/{auth.d.ts → daemon/auth.d.ts} +1 -2
  53. package/esm/daemon/auth.d.ts.map +1 -0
  54. package/esm/{auth.js → daemon/auth.js} +14 -14
  55. package/esm/daemon/auth.js.map +1 -0
  56. package/esm/daemon/connection.d.ts +11 -0
  57. package/esm/daemon/connection.d.ts.map +1 -0
  58. package/esm/daemon/connection.js +2 -0
  59. package/esm/daemon/connection.js.map +1 -0
  60. package/esm/{crypto.d.ts → daemon/crypto.d.ts} +5 -5
  61. package/esm/daemon/crypto.d.ts.map +1 -0
  62. package/esm/{crypto.js → daemon/crypto.js} +23 -27
  63. package/esm/daemon/crypto.js.map +1 -0
  64. package/esm/{backend.d.ts → daemon/device.d.ts} +2 -2
  65. package/esm/daemon/device.d.ts.map +1 -0
  66. package/esm/daemon/device.js +2 -0
  67. package/esm/daemon/device.js.map +1 -0
  68. package/esm/{socket → daemon}/dispatcher.d.ts +8 -26
  69. package/esm/daemon/dispatcher.d.ts.map +1 -0
  70. package/esm/{socket → daemon}/dispatcher.js +65 -63
  71. package/esm/daemon/dispatcher.js.map +1 -0
  72. package/esm/daemon/index.d.ts +8 -0
  73. package/esm/daemon/index.d.ts.map +1 -0
  74. package/esm/daemon/index.js +8 -0
  75. package/esm/daemon/index.js.map +1 -0
  76. package/esm/{packet.d.ts → daemon/packet.d.ts} +4 -4
  77. package/esm/daemon/packet.d.ts.map +1 -0
  78. package/esm/{packet.js → daemon/packet.js} +1 -1
  79. package/esm/daemon/packet.js.map +1 -0
  80. package/esm/{socket → daemon}/socket.d.ts +15 -17
  81. package/esm/daemon/socket.d.ts.map +1 -0
  82. package/esm/{socket → daemon}/socket.js +38 -35
  83. package/esm/daemon/socket.js.map +1 -0
  84. package/esm/daemon/transport.d.ts +45 -0
  85. package/esm/daemon/transport.d.ts.map +1 -0
  86. package/esm/daemon/transport.js +184 -0
  87. package/esm/daemon/transport.js.map +1 -0
  88. package/esm/index.d.ts +3 -5
  89. package/esm/index.d.ts.map +1 -1
  90. package/esm/index.js +3 -5
  91. package/esm/index.js.map +1 -1
  92. package/esm/server/client.d.ts +78 -0
  93. package/esm/server/client.d.ts.map +1 -0
  94. package/esm/server/client.js +329 -0
  95. package/esm/server/client.js.map +1 -0
  96. package/esm/server/index.d.ts +3 -0
  97. package/esm/server/index.d.ts.map +1 -0
  98. package/esm/server/index.js +3 -0
  99. package/esm/server/index.js.map +1 -0
  100. package/esm/server/transport.d.ts +19 -0
  101. package/esm/server/transport.d.ts.map +1 -0
  102. package/esm/server/transport.js +44 -0
  103. package/esm/server/transport.js.map +1 -0
  104. package/esm/utils/auto-reset-event.d.ts +1 -2
  105. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  106. package/esm/utils/auto-reset-event.js +12 -12
  107. package/esm/utils/auto-reset-event.js.map +1 -1
  108. package/esm/utils/base64.js +5 -5
  109. package/esm/utils/base64.js.map +1 -1
  110. package/esm/utils/conditional-variable.d.ts +1 -2
  111. package/esm/utils/conditional-variable.d.ts.map +1 -1
  112. package/esm/utils/conditional-variable.js +10 -10
  113. package/esm/utils/conditional-variable.js.map +1 -1
  114. package/esm/utils/hex.d.ts +3 -0
  115. package/esm/utils/hex.d.ts.map +1 -0
  116. package/esm/utils/hex.js +55 -0
  117. package/esm/utils/hex.js.map +1 -0
  118. package/esm/utils/index.d.ts +2 -0
  119. package/esm/utils/index.d.ts.map +1 -1
  120. package/esm/utils/index.js +2 -0
  121. package/esm/utils/index.js.map +1 -1
  122. package/esm/utils/no-op.d.ts +7 -0
  123. package/esm/utils/no-op.d.ts.map +1 -0
  124. package/esm/utils/no-op.js +12 -0
  125. package/esm/utils/no-op.js.map +1 -0
  126. package/package.json +11 -10
  127. package/src/adb.ts +41 -252
  128. package/src/banner.ts +82 -0
  129. package/src/commands/power.ts +2 -2
  130. package/src/commands/reverse.ts +68 -73
  131. package/src/commands/subprocess/protocols/none.ts +17 -18
  132. package/src/commands/subprocess/protocols/shell.ts +54 -56
  133. package/src/commands/subprocess/protocols/types.ts +1 -2
  134. package/src/commands/sync/list.ts +2 -2
  135. package/src/commands/sync/push.ts +22 -10
  136. package/src/commands/sync/request.ts +1 -1
  137. package/src/commands/sync/response.ts +6 -6
  138. package/src/commands/sync/socket.ts +37 -35
  139. package/src/commands/sync/sync.ts +25 -28
  140. package/src/commands/tcpip.ts +6 -4
  141. package/src/{auth.ts → daemon/auth.ts} +17 -17
  142. package/src/{crypto.ts → daemon/crypto.ts} +25 -33
  143. package/src/{backend.ts → daemon/device.ts} +1 -1
  144. package/src/{socket → daemon}/dispatcher.ts +71 -78
  145. package/src/daemon/index.ts +7 -0
  146. package/src/{packet.ts → daemon/packet.ts} +5 -5
  147. package/src/{socket → daemon}/socket.ts +50 -44
  148. package/src/daemon/transport.ts +269 -0
  149. package/src/index.ts +3 -5
  150. package/src/server/client.ts +476 -0
  151. package/src/server/index.ts +2 -0
  152. package/src/server/transport.ts +77 -0
  153. package/src/utils/auto-reset-event.ts +12 -12
  154. package/src/utils/conditional-variable.ts +10 -10
  155. package/src/utils/hex.ts +58 -0
  156. package/src/utils/index.ts +2 -0
  157. package/src/utils/no-op.ts +12 -0
  158. package/tsconfig.build.json +12 -1
  159. package/tsconfig.build.tsbuildinfo +1 -1
  160. package/esm/auth.d.ts.map +0 -1
  161. package/esm/auth.js.map +0 -1
  162. package/esm/backend.d.ts.map +0 -1
  163. package/esm/backend.js +0 -2
  164. package/esm/backend.js.map +0 -1
  165. package/esm/commands/install.d.ts +0 -10
  166. package/esm/commands/install.d.ts.map +0 -1
  167. package/esm/commands/install.js +0 -29
  168. package/esm/commands/install.js.map +0 -1
  169. package/esm/crypto.d.ts.map +0 -1
  170. package/esm/crypto.js.map +0 -1
  171. package/esm/packet.d.ts.map +0 -1
  172. package/esm/packet.js.map +0 -1
  173. package/esm/socket/dispatcher.d.ts.map +0 -1
  174. package/esm/socket/dispatcher.js.map +0 -1
  175. package/esm/socket/index.d.ts +0 -3
  176. package/esm/socket/index.d.ts.map +0 -1
  177. package/esm/socket/index.js +0 -3
  178. package/esm/socket/index.js.map +0 -1
  179. package/esm/socket/socket.d.ts.map +0 -1
  180. package/esm/socket/socket.js.map +0 -1
  181. package/src/socket/index.ts +0 -2
@@ -1,5 +1,4 @@
1
1
  import { AsyncOperationManager, PromiseResolver } from "@yume-chan/async";
2
- import type { RemoveEventListener } from "@yume-chan/event";
3
2
  import type {
4
3
  Consumable,
5
4
  ReadableWritablePair,
@@ -10,15 +9,14 @@ import {
10
9
  ConsumableWritableStream,
11
10
  WritableStream,
12
11
  } from "@yume-chan/stream-extra";
13
- import type { ValueOrPromise } from "@yume-chan/struct";
14
12
  import { EMPTY_UINT8_ARRAY } from "@yume-chan/struct";
15
13
 
16
- import type { AdbPacketData, AdbPacketInit } from "../packet.js";
17
- import { AdbCommand, calculateChecksum } from "../packet.js";
18
- import { decodeUtf8, encodeUtf8 } from "../utils/index.js";
14
+ import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "../adb.js";
15
+ import { decodeUtf8, encodeUtf8, unreachable } from "../utils/index.js";
19
16
 
20
- import type { AdbSocket } from "./socket.js";
21
- import { AdbSocketController } from "./socket.js";
17
+ import type { AdbPacketData, AdbPacketInit } from "./packet.js";
18
+ import { AdbCommand, calculateChecksum } from "./packet.js";
19
+ import { AdbDaemonSocketController } from "./socket.js";
22
20
 
23
21
  export interface AdbPacketDispatcherOptions {
24
22
  calculateChecksum: boolean;
@@ -32,14 +30,6 @@ export interface AdbPacketDispatcherOptions {
32
30
  maxPayloadSize: number;
33
31
  }
34
32
 
35
- export type AdbIncomingSocketHandler = (
36
- socket: AdbSocket
37
- ) => ValueOrPromise<boolean>;
38
-
39
- export interface Closeable {
40
- close(): ValueOrPromise<void>;
41
- }
42
-
43
33
  /**
44
34
  * The dispatcher is the "dumb" part of the connection handling logic.
45
35
  *
@@ -53,25 +43,24 @@ export interface Closeable {
53
43
  export class AdbPacketDispatcher implements Closeable {
54
44
  // ADB socket id starts from 1
55
45
  // (0 means open failed)
56
- private readonly initializers = new AsyncOperationManager(1);
46
+ readonly #initializers = new AsyncOperationManager(1);
57
47
  /**
58
48
  * Socket local ID to the socket controller.
59
49
  */
60
- private readonly sockets = new Map<number, AdbSocketController>();
50
+ readonly #sockets = new Map<number, AdbDaemonSocketController>();
61
51
 
62
- private _writer: WritableStreamDefaultWriter<Consumable<AdbPacketInit>>;
52
+ #writer: WritableStreamDefaultWriter<Consumable<AdbPacketInit>>;
63
53
 
64
54
  public readonly options: AdbPacketDispatcherOptions;
65
55
 
66
- private _closed = false;
67
- private _disconnected = new PromiseResolver<void>();
56
+ #closed = false;
57
+ #disconnected = new PromiseResolver<void>();
68
58
  public get disconnected() {
69
- return this._disconnected.promise;
59
+ return this.#disconnected.promise;
70
60
  }
71
61
 
72
- private _incomingSocketHandlers: Set<AdbIncomingSocketHandler> = new Set();
73
-
74
- private _abortController = new AbortController();
62
+ #incomingSocketHandlers = new Map<string, AdbIncomingSocketHandler>();
63
+ #readAbortController = new AbortController();
75
64
 
76
65
  public constructor(
77
66
  connection: ReadableWritablePair<
@@ -94,8 +83,8 @@ export class AdbPacketDispatcher implements Closeable {
94
83
  await this.handleClose(packet);
95
84
  break;
96
85
  case AdbCommand.Write:
97
- if (this.sockets.has(packet.arg1)) {
98
- await this.sockets
86
+ if (this.#sockets.has(packet.arg1)) {
87
+ await this.#sockets
99
88
  .get(packet.arg1)!
100
89
  .enqueue(packet.payload);
101
90
  await this.sendPacket(
@@ -131,7 +120,7 @@ export class AdbPacketDispatcher implements Closeable {
131
120
  // it's still possible to create another ADB connection.
132
121
  // So don't close `readable` here.
133
122
  preventCancel: true,
134
- signal: this._abortController.signal,
123
+ signal: this.#readAbortController.signal,
135
124
  }
136
125
  )
137
126
  .then(
@@ -139,23 +128,23 @@ export class AdbPacketDispatcher implements Closeable {
139
128
  this.dispose();
140
129
  },
141
130
  (e) => {
142
- if (!this._closed) {
143
- this._disconnected.reject(e);
131
+ if (!this.#closed) {
132
+ this.#disconnected.reject(e);
144
133
  }
145
134
  this.dispose();
146
135
  }
147
136
  );
148
137
 
149
- this._writer = connection.writable.getWriter();
138
+ this.#writer = connection.writable.getWriter();
150
139
  }
151
140
 
152
141
  private handleOk(packet: AdbPacketData) {
153
- if (this.initializers.resolve(packet.arg1, packet.arg0)) {
142
+ if (this.#initializers.resolve(packet.arg1, packet.arg0)) {
154
143
  // Device successfully created the socket
155
144
  return;
156
145
  }
157
146
 
158
- const socket = this.sockets.get(packet.arg1);
147
+ const socket = this.#sockets.get(packet.arg1);
159
148
  if (socket) {
160
149
  // Device has received last `WRTE` to the socket
161
150
  socket.ack();
@@ -171,7 +160,7 @@ export class AdbPacketDispatcher implements Closeable {
171
160
  // If the socket is still pending
172
161
  if (
173
162
  packet.arg0 === 0 &&
174
- this.initializers.reject(
163
+ this.#initializers.reject(
175
164
  packet.arg1,
176
165
  new Error("Socket open failed")
177
166
  )
@@ -192,7 +181,7 @@ export class AdbPacketDispatcher implements Closeable {
192
181
  */
193
182
 
194
183
  // Ignore `arg0` and search for the socket
195
- const socket = this.sockets.get(packet.arg1);
184
+ const socket = this.#sockets.get(packet.arg1);
196
185
  if (socket) {
197
186
  // The device want to close the socket
198
187
  if (!socket.closed) {
@@ -203,7 +192,7 @@ export class AdbPacketDispatcher implements Closeable {
203
192
  );
204
193
  }
205
194
  await socket.dispose();
206
- this.sockets.delete(packet.arg1);
195
+ this.#sockets.delete(packet.arg1);
207
196
  return;
208
197
  }
209
198
 
@@ -212,68 +201,74 @@ export class AdbPacketDispatcher implements Closeable {
212
201
  // the device may also respond with two `CLSE` packets.
213
202
  }
214
203
 
215
- /**
216
- * Add a handler for incoming socket.
217
- * @param handler A function to call with new incoming sockets. It must return `true` if it accepts the socket.
218
- * @returns A function to remove the handler.
219
- */
220
- public onIncomingSocket(
204
+ public addReverseTunnel(
205
+ service: string,
221
206
  handler: AdbIncomingSocketHandler
222
- ): RemoveEventListener {
223
- this._incomingSocketHandlers.add(handler);
224
- const remove = () => {
225
- this._incomingSocketHandlers.delete(handler);
226
- };
227
- remove.dispose = remove;
228
- return remove;
207
+ ) {
208
+ this.#incomingSocketHandlers.set(service, handler);
209
+ }
210
+
211
+ public removeReverseTunnel(address: string) {
212
+ this.#incomingSocketHandlers.delete(address);
213
+ }
214
+
215
+ public clearReverseTunnels() {
216
+ this.#incomingSocketHandlers.clear();
229
217
  }
230
218
 
231
219
  private async handleOpen(packet: AdbPacketData) {
232
220
  // `AsyncOperationManager` doesn't support skipping IDs
233
221
  // Use `add` + `resolve` to simulate this behavior
234
- const [localId] = this.initializers.add<number>();
235
- this.initializers.resolve(localId, undefined);
222
+ const [localId] = this.#initializers.add<number>();
223
+ this.#initializers.resolve(localId, undefined);
236
224
 
237
225
  const remoteId = packet.arg0;
238
- const serviceString = decodeUtf8(packet.payload);
226
+ let service = decodeUtf8(packet.payload);
227
+ if (service.endsWith("\0")) {
228
+ service = service.substring(0, service.length - 1);
229
+ }
230
+
231
+ const handler = this.#incomingSocketHandlers.get(service);
232
+ if (!handler) {
233
+ await this.sendPacket(AdbCommand.Close, 0, remoteId);
234
+ return;
235
+ }
239
236
 
240
- const controller = new AdbSocketController({
237
+ const controller = new AdbDaemonSocketController({
241
238
  dispatcher: this,
242
239
  localId,
243
240
  remoteId,
244
241
  localCreated: false,
245
- serviceString,
242
+ service,
246
243
  });
247
244
 
248
- for (const handler of this._incomingSocketHandlers) {
249
- if (await handler(controller.socket)) {
250
- this.sockets.set(localId, controller);
251
- await this.sendPacket(AdbCommand.OK, localId, remoteId);
252
- return;
253
- }
245
+ try {
246
+ await handler(controller.socket);
247
+ this.#sockets.set(localId, controller);
248
+ await this.sendPacket(AdbCommand.OK, localId, remoteId);
249
+ } catch (e) {
250
+ await this.sendPacket(AdbCommand.Close, 0, remoteId);
254
251
  }
255
-
256
- await this.sendPacket(AdbCommand.Close, 0, remoteId);
257
252
  }
258
253
 
259
- public async createSocket(serviceString: string): Promise<AdbSocket> {
254
+ public async createSocket(service: string): Promise<AdbSocket> {
260
255
  if (this.options.appendNullToServiceString) {
261
- serviceString += "\0";
256
+ service += "\0";
262
257
  }
263
258
 
264
- const [localId, initializer] = this.initializers.add<number>();
265
- await this.sendPacket(AdbCommand.Open, localId, 0, serviceString);
259
+ const [localId, initializer] = this.#initializers.add<number>();
260
+ await this.sendPacket(AdbCommand.Open, localId, 0, service);
266
261
 
267
262
  // Fulfilled by `handleOk`
268
263
  const remoteId = await initializer;
269
- const controller = new AdbSocketController({
264
+ const controller = new AdbDaemonSocketController({
270
265
  dispatcher: this,
271
266
  localId,
272
267
  remoteId,
273
268
  localCreated: true,
274
- serviceString,
269
+ service,
275
270
  });
276
- this.sockets.set(localId, controller);
271
+ this.#sockets.set(localId, controller);
277
272
 
278
273
  return controller.socket;
279
274
  }
@@ -292,7 +287,7 @@ export class AdbPacketDispatcher implements Closeable {
292
287
  throw new Error("payload too large");
293
288
  }
294
289
 
295
- await ConsumableWritableStream.write(this._writer, {
290
+ await ConsumableWritableStream.write(this.#writer, {
296
291
  command,
297
292
  arg0,
298
293
  arg1,
@@ -307,26 +302,24 @@ export class AdbPacketDispatcher implements Closeable {
307
302
  public async close() {
308
303
  // Send `CLSE` packets for all sockets
309
304
  await Promise.all(
310
- Array.from(this.sockets.values(), (socket) => socket.close())
305
+ Array.from(this.#sockets.values(), (socket) => socket.close())
311
306
  );
312
307
 
313
308
  // Stop receiving
314
309
  // It's possible that we haven't received all `CLSE` confirm packets,
315
310
  // but it doesn't matter, the next connection can cope with them.
316
- this._closed = true;
317
- this._abortController.abort();
318
- this._writer.releaseLock();
311
+ this.#closed = true;
312
+ this.#readAbortController.abort();
313
+ this.#writer.releaseLock();
319
314
 
320
315
  // `pipe().then()` will call `dispose`
321
316
  }
322
317
 
323
318
  private dispose() {
324
- for (const socket of this.sockets.values()) {
325
- socket.dispose().catch((e) => {
326
- void e;
327
- });
319
+ for (const socket of this.#sockets.values()) {
320
+ socket.dispose().catch(unreachable);
328
321
  }
329
322
 
330
- this._disconnected.resolve();
323
+ this.#disconnected.resolve();
331
324
  }
332
325
  }
@@ -0,0 +1,7 @@
1
+ export * from "./auth.js";
2
+ export * from "./crypto.js";
3
+ export * from "./device.js";
4
+ export * from "./dispatcher.js";
5
+ export * from "./packet.js";
6
+ export * from "./socket.js";
7
+ export * from "./transport.js";
@@ -23,7 +23,7 @@ export type AdbPacketHeader = (typeof AdbPacketHeader)["TDeserializeResult"];
23
23
  type AdbPacketHeaderInit = (typeof AdbPacketHeader)["TInit"];
24
24
 
25
25
  export const AdbPacket = new Struct({ littleEndian: true })
26
- .fields(AdbPacketHeader)
26
+ .concat(AdbPacketHeader)
27
27
  .uint8Array("payload", { lengthField: "payloadLength" });
28
28
 
29
29
  export type AdbPacket = (typeof AdbPacket)["TDeserializeResult"];
@@ -31,11 +31,11 @@ export type AdbPacket = (typeof AdbPacket)["TDeserializeResult"];
31
31
  /**
32
32
  * `AdbPacketData` contains all the useful fields of `AdbPacket`.
33
33
  *
34
- * `AdbBackend#connect` will return a `ReadableStream<AdbPacketData>`,
35
- * so each backend can encode `AdbPacket` in different ways.
34
+ * `AdvDaemonConnection#connect` will return a `ReadableStream<AdbPacketData>`,
35
+ * allow each connection to encode `AdbPacket` in different methods.
36
36
  *
37
- * `AdbBackend#connect` will return a `WritableStream<AdbPacketInit>`,
38
- * however, `AdbPacketDispatcher` will transform `AdbPacketData` to `AdbPacketInit` for you,
37
+ * `AdbDaemonConnection#connect` will return a `WritableStream<AdbPacketInit>`,
38
+ * however, `AdbDaemonTransport` will transform `AdbPacketData` to `AdbPacketInit` for you,
39
39
  * so `AdbSocket#writable#write` only needs `AdbPacketData`.
40
40
  */
41
41
  export type AdbPacketData = Omit<
@@ -15,27 +15,29 @@ import {
15
15
  pipeFrom,
16
16
  } from "@yume-chan/stream-extra";
17
17
 
18
- import { AdbCommand } from "../packet.js";
18
+ import type { Closeable } from "../adb.js";
19
19
 
20
- import type { AdbPacketDispatcher, Closeable } from "./dispatcher.js";
20
+ import type { AdbPacketDispatcher } from "./dispatcher.js";
21
+ import { AdbCommand } from "./packet.js";
21
22
 
22
- export interface AdbSocketInfo {
23
+ export interface AdbDaemonSocketInfo {
23
24
  localId: number;
24
25
  remoteId: number;
25
26
 
26
27
  localCreated: boolean;
27
- serviceString: string;
28
+ service: string;
28
29
  }
29
30
 
30
- export interface AdbSocketConstructionOptions extends AdbSocketInfo {
31
+ export interface AdbDaemonSocketConstructionOptions
32
+ extends AdbDaemonSocketInfo {
31
33
  dispatcher: AdbPacketDispatcher;
32
34
 
33
35
  highWaterMark?: number | undefined;
34
36
  }
35
37
 
36
- export class AdbSocketController
38
+ export class AdbDaemonSocketController
37
39
  implements
38
- AdbSocketInfo,
40
+ AdbDaemonSocketInfo,
39
41
  ReadableWritablePair<Uint8Array, Consumable<Uint8Array>>,
40
42
  Closeable,
41
43
  Disposable
@@ -45,47 +47,47 @@ export class AdbSocketController
45
47
  public readonly localId!: number;
46
48
  public readonly remoteId!: number;
47
49
  public readonly localCreated!: boolean;
48
- public readonly serviceString!: string;
50
+ public readonly service!: string;
49
51
 
50
- private _duplex: DuplexStreamFactory<Uint8Array, Consumable<Uint8Array>>;
52
+ #duplex: DuplexStreamFactory<Uint8Array, Consumable<Uint8Array>>;
51
53
 
52
- private _readable: ReadableStream<Uint8Array>;
53
- private _readableController!: PushReadableStreamController<Uint8Array>;
54
+ #readable: ReadableStream<Uint8Array>;
55
+ #readableController!: PushReadableStreamController<Uint8Array>;
54
56
  public get readable() {
55
- return this._readable;
57
+ return this.#readable;
56
58
  }
57
59
 
58
- private _writePromise: PromiseResolver<void> | undefined;
60
+ #writePromise: PromiseResolver<void> | undefined;
59
61
  public readonly writable: WritableStream<Consumable<Uint8Array>>;
60
62
 
61
- private _closed = false;
63
+ #closed = false;
62
64
  /**
63
65
  * Whether the socket is half-closed (i.e. the local side initiated the close).
64
66
  *
65
67
  * It's only used by dispatcher to avoid sending another `CLSE` packet to remote.
66
68
  */
67
69
  public get closed() {
68
- return this._closed;
70
+ return this.#closed;
69
71
  }
70
72
 
71
- private _socket: AdbSocket;
73
+ private _socket: AdbDaemonSocket;
72
74
  public get socket() {
73
75
  return this._socket;
74
76
  }
75
77
 
76
- public constructor(options: AdbSocketConstructionOptions) {
78
+ public constructor(options: AdbDaemonSocketConstructionOptions) {
77
79
  Object.assign(this, options);
78
80
 
79
81
  // Check this image to help you understand the stream graph
80
82
  // cspell: disable-next-line
81
83
  // https://www.plantuml.com/plantuml/png/TL0zoeGm4ErpYc3l5JxyS0yWM6mX5j4C6p4cxcJ25ejttuGX88ZftizxUKmJI275pGhXl0PP_UkfK_CAz5Z2hcWsW9Ny2fdU4C1f5aSchFVxA8vJjlTPRhqZzDQMRB7AklwJ0xXtX0ZSKH1h24ghoKAdGY23FhxC4nS2pDvxzIvxb-8THU0XlEQJ-ZB7SnXTAvc_LhOckhMdLBnbtndpb-SB7a8q2SRD_W00
82
84
 
83
- this._duplex = new DuplexStreamFactory<
85
+ this.#duplex = new DuplexStreamFactory<
84
86
  Uint8Array,
85
87
  Consumable<Uint8Array>
86
88
  >({
87
89
  close: async () => {
88
- this._closed = true;
90
+ this.#closed = true;
89
91
 
90
92
  await this.dispatcher.sendPacket(
91
93
  AdbCommand.Close,
@@ -98,14 +100,14 @@ export class AdbSocketController
98
100
  },
99
101
  dispose: () => {
100
102
  // Error out the pending writes
101
- this._writePromise?.reject(new Error("Socket closed"));
103
+ this.#writePromise?.reject(new Error("Socket closed"));
102
104
  },
103
105
  });
104
106
 
105
- this._readable = this._duplex.wrapReadable(
107
+ this.#readable = this.#duplex.wrapReadable(
106
108
  new PushReadableStream(
107
109
  (controller) => {
108
- this._readableController = controller;
110
+ this.#readableController = controller;
109
111
  },
110
112
  {
111
113
  highWaterMark: options.highWaterMark ?? 16 * 1024,
@@ -117,47 +119,47 @@ export class AdbSocketController
117
119
  );
118
120
 
119
121
  this.writable = pipeFrom(
120
- this._duplex.createWritable(
122
+ this.#duplex.createWritable(
121
123
  new ConsumableWritableStream<Uint8Array>({
122
124
  write: async (chunk) => {
123
125
  // Wait for an ack packet
124
- this._writePromise = new PromiseResolver();
126
+ this.#writePromise = new PromiseResolver();
125
127
  await this.dispatcher.sendPacket(
126
128
  AdbCommand.Write,
127
129
  this.localId,
128
130
  this.remoteId,
129
131
  chunk
130
132
  );
131
- await this._writePromise.promise;
133
+ await this.#writePromise.promise;
132
134
  },
133
135
  })
134
136
  ),
135
137
  new DistributionStream(this.dispatcher.options.maxPayloadSize)
136
138
  );
137
139
 
138
- this._socket = new AdbSocket(this);
140
+ this._socket = new AdbDaemonSocket(this);
139
141
  }
140
142
 
141
143
  public async enqueue(data: Uint8Array) {
142
144
  // Consumer may abort the `ReadableStream` to close the socket,
143
145
  // it's OK to throw away further packets in this case.
144
- if (this._readableController.abortSignal.aborted) {
146
+ if (this.#readableController.abortSignal.aborted) {
145
147
  return;
146
148
  }
147
149
 
148
- await this._readableController.enqueue(data);
150
+ await this.#readableController.enqueue(data);
149
151
  }
150
152
 
151
153
  public ack() {
152
- this._writePromise?.resolve();
154
+ this.#writePromise?.resolve();
153
155
  }
154
156
 
155
157
  public async close(): Promise<void> {
156
- await this._duplex.close();
158
+ await this.#duplex.close();
157
159
  }
158
160
 
159
161
  public dispose() {
160
- return this._duplex.dispose();
162
+ return this.#duplex.dispose();
161
163
  }
162
164
  }
163
165
 
@@ -169,38 +171,42 @@ export class AdbSocketController
169
171
  * `socket.writable.abort()`, `socket.writable.getWriter().abort()`,
170
172
  * `socket.writable.close()` or `socket.writable.getWriter().close()`.
171
173
  */
172
- export class AdbSocket
174
+ export class AdbDaemonSocket
173
175
  implements
174
- AdbSocketInfo,
176
+ AdbDaemonSocketInfo,
175
177
  ReadableWritablePair<Uint8Array, Consumable<Uint8Array>>
176
178
  {
177
- private _controller: AdbSocketController;
179
+ #controller: AdbDaemonSocketController;
178
180
 
179
181
  public get localId(): number {
180
- return this._controller.localId;
182
+ return this.#controller.localId;
181
183
  }
182
184
  public get remoteId(): number {
183
- return this._controller.remoteId;
185
+ return this.#controller.remoteId;
184
186
  }
185
187
  public get localCreated(): boolean {
186
- return this._controller.localCreated;
188
+ return this.#controller.localCreated;
187
189
  }
188
- public get serviceString(): string {
189
- return this._controller.serviceString;
190
+ public get service(): string {
191
+ return this.#controller.service;
190
192
  }
191
193
 
192
194
  public get readable(): ReadableStream<Uint8Array> {
193
- return this._controller.readable;
195
+ return this.#controller.readable;
194
196
  }
195
197
  public get writable(): WritableStream<Consumable<Uint8Array>> {
196
- return this._controller.writable;
198
+ return this.#controller.writable;
197
199
  }
198
200
 
199
- public constructor(controller: AdbSocketController) {
200
- this._controller = controller;
201
+ public get closed(): boolean {
202
+ return this.#controller.closed;
203
+ }
204
+
205
+ public constructor(controller: AdbDaemonSocketController) {
206
+ this.#controller = controller;
201
207
  }
202
208
 
203
209
  public close() {
204
- return this._controller.close();
210
+ return this.#controller.close();
205
211
  }
206
212
  }