@yume-chan/adb 0.0.20 → 0.0.22

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 (132) hide show
  1. package/CHANGELOG.json +45 -0
  2. package/CHANGELOG.md +22 -1
  3. package/README.md +46 -364
  4. package/esm/adb.d.ts +9 -5
  5. package/esm/adb.d.ts.map +1 -1
  6. package/esm/adb.js +21 -11
  7. package/esm/adb.js.map +1 -1
  8. package/esm/banner.d.ts.map +1 -1
  9. package/esm/banner.js +1 -1
  10. package/esm/banner.js.map +1 -1
  11. package/esm/commands/base.d.ts.map +1 -1
  12. package/esm/commands/base.js.map +1 -1
  13. package/esm/commands/framebuffer.d.ts +9 -0
  14. package/esm/commands/framebuffer.d.ts.map +1 -1
  15. package/esm/commands/framebuffer.js +27 -3
  16. package/esm/commands/framebuffer.js.map +1 -1
  17. package/esm/commands/power.d.ts.map +1 -1
  18. package/esm/commands/power.js.map +1 -1
  19. package/esm/commands/reverse.d.ts.map +1 -1
  20. package/esm/commands/reverse.js.map +1 -1
  21. package/esm/commands/subprocess/command.d.ts +1 -1
  22. package/esm/commands/subprocess/command.d.ts.map +1 -1
  23. package/esm/commands/subprocess/command.js +15 -13
  24. package/esm/commands/subprocess/command.js.map +1 -1
  25. package/esm/commands/subprocess/protocols/none.d.ts +2 -1
  26. package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
  27. package/esm/commands/subprocess/protocols/none.js +11 -14
  28. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  29. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  30. package/esm/commands/subprocess/protocols/shell.js +21 -17
  31. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  32. package/esm/commands/subprocess/utils.js.map +1 -1
  33. package/esm/commands/sync/list.d.ts +2 -1
  34. package/esm/commands/sync/list.d.ts.map +1 -1
  35. package/esm/commands/sync/list.js +2 -2
  36. package/esm/commands/sync/list.js.map +1 -1
  37. package/esm/commands/sync/pull.d.ts.map +1 -1
  38. package/esm/commands/sync/pull.js +4 -0
  39. package/esm/commands/sync/pull.js.map +1 -1
  40. package/esm/commands/sync/push.js +1 -1
  41. package/esm/commands/sync/push.js.map +1 -1
  42. package/esm/commands/sync/request.js +1 -1
  43. package/esm/commands/sync/request.js.map +1 -1
  44. package/esm/commands/sync/response.d.ts +3 -1
  45. package/esm/commands/sync/response.d.ts.map +1 -1
  46. package/esm/commands/sync/response.js +5 -3
  47. package/esm/commands/sync/response.js.map +1 -1
  48. package/esm/commands/sync/socket.d.ts +1 -1
  49. package/esm/commands/sync/socket.d.ts.map +1 -1
  50. package/esm/commands/sync/socket.js +7 -3
  51. package/esm/commands/sync/socket.js.map +1 -1
  52. package/esm/commands/sync/stat.js +2 -2
  53. package/esm/commands/sync/stat.js.map +1 -1
  54. package/esm/commands/sync/sync.d.ts +15 -0
  55. package/esm/commands/sync/sync.d.ts.map +1 -1
  56. package/esm/commands/sync/sync.js +17 -2
  57. package/esm/commands/sync/sync.js.map +1 -1
  58. package/esm/commands/tcpip.d.ts +21 -0
  59. package/esm/commands/tcpip.d.ts.map +1 -1
  60. package/esm/commands/tcpip.js +18 -0
  61. package/esm/commands/tcpip.js.map +1 -1
  62. package/esm/daemon/auth.d.ts +11 -9
  63. package/esm/daemon/auth.d.ts.map +1 -1
  64. package/esm/daemon/auth.js +21 -12
  65. package/esm/daemon/auth.js.map +1 -1
  66. package/esm/daemon/crypto.js +2 -2
  67. package/esm/daemon/crypto.js.map +1 -1
  68. package/esm/daemon/dispatcher.d.ts +6 -5
  69. package/esm/daemon/dispatcher.d.ts.map +1 -1
  70. package/esm/daemon/dispatcher.js +69 -58
  71. package/esm/daemon/dispatcher.js.map +1 -1
  72. package/esm/daemon/packet.d.ts +5 -5
  73. package/esm/daemon/packet.d.ts.map +1 -1
  74. package/esm/daemon/packet.js +2 -2
  75. package/esm/daemon/packet.js.map +1 -1
  76. package/esm/daemon/socket.d.ts +7 -14
  77. package/esm/daemon/socket.d.ts.map +1 -1
  78. package/esm/daemon/socket.js +58 -46
  79. package/esm/daemon/socket.js.map +1 -1
  80. package/esm/daemon/transport.d.ts +16 -4
  81. package/esm/daemon/transport.d.ts.map +1 -1
  82. package/esm/daemon/transport.js +11 -7
  83. package/esm/daemon/transport.js.map +1 -1
  84. package/esm/features.js +1 -1
  85. package/esm/features.js.map +1 -1
  86. package/esm/server/client.d.ts +12 -8
  87. package/esm/server/client.d.ts.map +1 -1
  88. package/esm/server/client.js +41 -22
  89. package/esm/server/client.js.map +1 -1
  90. package/esm/server/transport.d.ts.map +1 -1
  91. package/esm/server/transport.js.map +1 -1
  92. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  93. package/esm/utils/auto-reset-event.js.map +1 -1
  94. package/esm/utils/base64.js.map +1 -1
  95. package/esm/utils/conditional-variable.d.ts.map +1 -1
  96. package/esm/utils/conditional-variable.js.map +1 -1
  97. package/esm/utils/hex.js.map +1 -1
  98. package/package.json +13 -14
  99. package/src/adb.ts +49 -35
  100. package/src/banner.ts +7 -7
  101. package/src/commands/base.ts +1 -1
  102. package/src/commands/framebuffer.ts +31 -3
  103. package/src/commands/power.ts +9 -9
  104. package/src/commands/reverse.ts +13 -13
  105. package/src/commands/subprocess/command.ts +24 -25
  106. package/src/commands/subprocess/protocols/none.ts +23 -27
  107. package/src/commands/subprocess/protocols/shell.ts +42 -37
  108. package/src/commands/sync/list.ts +11 -7
  109. package/src/commands/sync/pull.ts +7 -4
  110. package/src/commands/sync/push.ts +6 -6
  111. package/src/commands/sync/request.ts +3 -3
  112. package/src/commands/sync/response.ts +8 -6
  113. package/src/commands/sync/socket.ts +19 -14
  114. package/src/commands/sync/stat.ts +5 -5
  115. package/src/commands/sync/sync.ts +32 -17
  116. package/src/commands/tcpip.ts +46 -2
  117. package/src/daemon/auth.ts +49 -30
  118. package/src/daemon/crypto.ts +9 -9
  119. package/src/daemon/dispatcher.ts +104 -88
  120. package/src/daemon/packet.ts +2 -2
  121. package/src/daemon/socket.ts +106 -115
  122. package/src/daemon/transport.ts +49 -29
  123. package/src/server/client.ts +88 -77
  124. package/src/server/transport.ts +13 -13
  125. package/src/utils/auto-reset-event.ts +4 -4
  126. package/src/utils/base64.ts +5 -5
  127. package/src/utils/conditional-variable.ts +4 -4
  128. package/tsconfig.build.tsbuildinfo +1 -1
  129. package/esm/daemon/connection.d.ts +0 -11
  130. package/esm/daemon/connection.d.ts.map +0 -1
  131. package/esm/daemon/connection.js +0 -2
  132. package/esm/daemon/connection.js.map +0 -1
@@ -61,38 +61,38 @@ class StdinSerializeStream extends ConsumableTransformStream<
61
61
  }
62
62
 
63
63
  class MultiplexStream<T> {
64
- private _readable: PushReadableStream<T>;
65
- private _readableController!: PushReadableStreamController<T>;
66
- public get readable() {
67
- return this._readable;
64
+ #readable: PushReadableStream<T>;
65
+ #readableController!: PushReadableStreamController<T>;
66
+ get readable() {
67
+ return this.#readable;
68
68
  }
69
69
 
70
- private _activeCount = 0;
70
+ #activeCount = 0;
71
71
 
72
72
  constructor() {
73
- this._readable = new PushReadableStream((controller) => {
74
- this._readableController = controller;
73
+ this.#readable = new PushReadableStream((controller) => {
74
+ this.#readableController = controller;
75
75
  });
76
76
  }
77
77
 
78
- public createWriteable() {
78
+ createWriteable() {
79
79
  return new WritableStream<T>({
80
80
  start: () => {
81
- this._activeCount += 1;
81
+ this.#activeCount += 1;
82
82
  },
83
83
  write: async (chunk) => {
84
- await this._readableController.enqueue(chunk);
84
+ await this.#readableController.enqueue(chunk);
85
85
  },
86
86
  abort: () => {
87
- this._activeCount -= 1;
88
- if (this._activeCount === 0) {
89
- this._readableController.close();
87
+ this.#activeCount -= 1;
88
+ if (this.#activeCount === 0) {
89
+ this.#readableController.close();
90
90
  }
91
91
  },
92
92
  close: () => {
93
- this._activeCount -= 1;
94
- if (this._activeCount === 0) {
95
- this._readableController.close();
93
+ this.#activeCount -= 1;
94
+ if (this.#activeCount === 0) {
95
+ this.#readableController.close();
96
96
  }
97
97
  },
98
98
  });
@@ -108,20 +108,20 @@ class MultiplexStream<T> {
108
108
  * * `resize`: Yes
109
109
  */
110
110
  export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
111
- public static isSupported(adb: Adb) {
111
+ static isSupported(adb: Adb) {
112
112
  return adb.supportsFeature(AdbFeature.ShellV2);
113
113
  }
114
114
 
115
- public static async pty(adb: Adb, command: string) {
115
+ static async pty(adb: Adb, command: string) {
116
116
  // TODO: AdbShellSubprocessProtocol: Support setting `XTERM` environment variable
117
117
  return new AdbSubprocessShellProtocol(
118
- await adb.createSocket(`shell,v2,pty:${command}`)
118
+ await adb.createSocket(`shell,v2,pty:${command}`),
119
119
  );
120
120
  }
121
121
 
122
- public static async raw(adb: Adb, command: string) {
122
+ static async raw(adb: Adb, command: string) {
123
123
  return new AdbSubprocessShellProtocol(
124
- await adb.createSocket(`shell,v2,raw:${command}`)
124
+ await adb.createSocket(`shell,v2,raw:${command}`),
125
125
  );
126
126
  }
127
127
 
@@ -131,26 +131,26 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
131
131
  >;
132
132
 
133
133
  #stdin: WritableStream<Consumable<Uint8Array>>;
134
- public get stdin() {
134
+ get stdin() {
135
135
  return this.#stdin;
136
136
  }
137
137
 
138
138
  #stdout: ReadableStream<Uint8Array>;
139
- public get stdout() {
139
+ get stdout() {
140
140
  return this.#stdout;
141
141
  }
142
142
 
143
143
  #stderr: ReadableStream<Uint8Array>;
144
- public get stderr() {
144
+ get stderr() {
145
145
  return this.#stderr;
146
146
  }
147
147
 
148
148
  readonly #exit = new PromiseResolver<number>();
149
- public get exit() {
149
+ get exit() {
150
150
  return this.#exit.promise;
151
151
  }
152
152
 
153
- public constructor(socket: AdbSocket) {
153
+ constructor(socket: AdbSocket) {
154
154
  this.#socket = socket;
155
155
 
156
156
  // Check this image to help you understand the stream graph
@@ -159,6 +159,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
159
159
 
160
160
  let stdoutController!: PushReadableStreamController<Uint8Array>;
161
161
  let stderrController!: PushReadableStreamController<Uint8Array>;
162
+
162
163
  this.#stdout = new PushReadableStream<Uint8Array>((controller) => {
163
164
  stdoutController = controller;
164
165
  });
@@ -176,14 +177,18 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
176
177
  this.#exit.resolve(chunk.data[0]!);
177
178
  break;
178
179
  case AdbShellProtocolId.Stdout:
179
- await stdoutController.enqueue(chunk.data);
180
+ if (!stdoutController.abortSignal.aborted) {
181
+ await stdoutController.enqueue(chunk.data);
182
+ }
180
183
  break;
181
184
  case AdbShellProtocolId.Stderr:
182
- await stderrController.enqueue(chunk.data);
185
+ if (!stderrController.abortSignal.aborted) {
186
+ await stderrController.enqueue(chunk.data);
187
+ }
183
188
  break;
184
189
  }
185
190
  },
186
- })
191
+ }),
187
192
  )
188
193
  .then(
189
194
  () => {
@@ -191,7 +196,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
191
196
  stderrController.close();
192
197
  // If `#exit` has already resolved, this will be a no-op
193
198
  this.#exit.reject(
194
- new Error("Socket ended without exit message")
199
+ new Error("Socket ended without exit message"),
195
200
  );
196
201
  },
197
202
  (e) => {
@@ -199,7 +204,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
199
204
  stderrController.error(e);
200
205
  // If `#exit` has already resolved, this will be a no-op
201
206
  this.#exit.reject(e);
202
- }
207
+ },
203
208
  );
204
209
 
205
210
  const multiplexer = new MultiplexStream<
@@ -210,34 +215,34 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
210
215
  new ConsumableTransformStream({
211
216
  async transform(chunk, controller) {
212
217
  await controller.enqueue(
213
- AdbShellProtocolPacket.serialize(chunk)
218
+ AdbShellProtocolPacket.serialize(chunk),
214
219
  );
215
220
  },
216
- })
221
+ }),
217
222
  )
218
223
  .pipeTo(socket.writable);
219
224
 
220
225
  this.#stdin = pipeFrom(
221
226
  multiplexer.createWriteable(),
222
- new StdinSerializeStream()
227
+ new StdinSerializeStream(),
223
228
  );
224
229
 
225
230
  this.#socketWriter = multiplexer.createWriteable().getWriter();
226
231
  }
227
232
 
228
- public async resize(rows: number, cols: number) {
233
+ async resize(rows: number, cols: number) {
229
234
  await ConsumableWritableStream.write(this.#socketWriter, {
230
235
  id: AdbShellProtocolId.WindowSizeChange,
231
236
  data: encodeUtf8(
232
237
  // The "correct" format is `${rows}x${cols},${x_pixels}x${y_pixels}`
233
238
  // However, according to https://linux.die.net/man/4/tty_ioctl
234
239
  // `x_pixels` and `y_pixels` are unused, so always sending `0` should be fine.
235
- `${rows}x${cols},0x0\0`
240
+ `${rows}x${cols},0x0\0`,
236
241
  ),
237
242
  });
238
243
  }
239
244
 
240
- public kill() {
245
+ kill() {
241
246
  return this.#socket.close();
242
247
  }
243
248
  }
@@ -4,7 +4,11 @@ import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
4
4
  import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
5
5
  import type { AdbSyncSocket } from "./socket.js";
6
6
  import type { AdbSyncStat } from "./stat.js";
7
- import { AdbSyncLstatResponse, AdbSyncStatResponse } from "./stat.js";
7
+ import {
8
+ AdbSyncLstatResponse,
9
+ AdbSyncStatErrorCode,
10
+ AdbSyncStatResponse,
11
+ } from "./stat.js";
8
12
 
9
13
  export interface AdbSyncEntry extends AdbSyncStat {
10
14
  name: string;
@@ -30,7 +34,7 @@ export type AdbSyncEntry2Response =
30
34
 
31
35
  export async function* adbSyncOpenDirV2(
32
36
  socket: AdbSyncSocket,
33
- path: string
37
+ path: string,
34
38
  ): AsyncGenerator<AdbSyncEntry2Response, void, void> {
35
39
  const locked = await socket.lock();
36
40
  try {
@@ -38,12 +42,12 @@ export async function* adbSyncOpenDirV2(
38
42
  for await (const item of adbSyncReadResponses(
39
43
  locked,
40
44
  AdbSyncResponseId.Entry2,
41
- AdbSyncEntry2Response
45
+ AdbSyncEntry2Response,
42
46
  )) {
43
47
  // `LST2` can return error codes for failed `lstat` calls.
44
48
  // `LIST` just ignores them.
45
49
  // But they only contain `name` so still pretty useless.
46
- if (item.error !== 0) {
50
+ if (item.error !== AdbSyncStatErrorCode.SUCCESS) {
47
51
  continue;
48
52
  }
49
53
  yield item;
@@ -55,7 +59,7 @@ export async function* adbSyncOpenDirV2(
55
59
 
56
60
  export async function* adbSyncOpenDirV1(
57
61
  socket: AdbSyncSocket,
58
- path: string
62
+ path: string,
59
63
  ): AsyncGenerator<AdbSyncEntryResponse, void, void> {
60
64
  const locked = await socket.lock();
61
65
  try {
@@ -63,7 +67,7 @@ export async function* adbSyncOpenDirV1(
63
67
  for await (const item of adbSyncReadResponses(
64
68
  locked,
65
69
  AdbSyncResponseId.Entry,
66
- AdbSyncEntryResponse
70
+ AdbSyncEntryResponse,
67
71
  )) {
68
72
  yield item;
69
73
  }
@@ -75,7 +79,7 @@ export async function* adbSyncOpenDirV1(
75
79
  export async function* adbSyncOpenDir(
76
80
  socket: AdbSyncSocket,
77
81
  path: string,
78
- v2: boolean
82
+ v2: boolean,
79
83
  ): AsyncGenerator<AdbSyncEntry, void, void> {
80
84
  if (v2) {
81
85
  yield* adbSyncOpenDirV2(socket, path);
@@ -16,7 +16,7 @@ export type AdbSyncDataResponse =
16
16
 
17
17
  export async function* adbSyncPullGenerator(
18
18
  socket: AdbSyncSocket,
19
- path: string
19
+ path: string,
20
20
  ): AsyncGenerator<Uint8Array, void, void> {
21
21
  const locked = await socket.lock();
22
22
  let done = false;
@@ -25,18 +25,21 @@ export async function* adbSyncPullGenerator(
25
25
  for await (const packet of adbSyncReadResponses(
26
26
  locked,
27
27
  AdbSyncResponseId.Data,
28
- AdbSyncDataResponse
28
+ AdbSyncDataResponse,
29
29
  )) {
30
30
  yield packet.data;
31
31
  }
32
32
  done = true;
33
+ } catch (e) {
34
+ done = true;
35
+ throw e;
33
36
  } finally {
34
37
  if (!done) {
35
38
  // sync pull can't be cancelled, so we have to read all data
36
39
  for await (const packet of adbSyncReadResponses(
37
40
  locked,
38
41
  AdbSyncResponseId.Data,
39
- AdbSyncDataResponse
42
+ AdbSyncDataResponse,
40
43
  )) {
41
44
  void packet;
42
45
  }
@@ -47,7 +50,7 @@ export async function* adbSyncPullGenerator(
47
50
 
48
51
  export function adbSyncPull(
49
52
  socket: AdbSyncSocket,
50
- path: string
53
+ path: string,
51
54
  ): ReadableStream<Uint8Array> {
52
55
  return new PushReadableStream(async (controller) => {
53
56
  for await (const data of adbSyncPullGenerator(socket, path)) {
@@ -26,14 +26,14 @@ export interface AdbSyncPushV1Options {
26
26
  }
27
27
 
28
28
  export const AdbSyncOkResponse = new Struct({ littleEndian: true }).uint32(
29
- "unused"
29
+ "unused",
30
30
  );
31
31
 
32
32
  async function pipeFileData(
33
33
  locked: AdbSyncSocketLocked,
34
34
  file: ReadableStream<Consumable<Uint8Array>>,
35
35
  packetSize: number,
36
- mtime: number
36
+ mtime: number,
37
37
  ) {
38
38
  // Read and write in parallel,
39
39
  // allow error response to abort the write.
@@ -45,11 +45,11 @@ async function pipeFileData(
45
45
  await adbSyncWriteRequest(
46
46
  locked,
47
47
  AdbSyncRequestId.Data,
48
- chunk
48
+ chunk,
49
49
  );
50
50
  },
51
51
  }),
52
- { signal: abortController.signal }
52
+ { signal: abortController.signal },
53
53
  )
54
54
  .then(async () => {
55
55
  await adbSyncWriteRequest(locked, AdbSyncRequestId.Done, mtime);
@@ -59,7 +59,7 @@ async function pipeFileData(
59
59
  await adbSyncReadResponse(
60
60
  locked,
61
61
  AdbSyncResponseId.Ok,
62
- AdbSyncOkResponse
62
+ AdbSyncOkResponse,
63
63
  ).catch((e) => {
64
64
  abortController.abort();
65
65
  throw e;
@@ -142,7 +142,7 @@ export async function adbSyncPushV2({
142
142
  id: AdbSyncRequestId.SendV2,
143
143
  mode,
144
144
  flags,
145
- })
145
+ }),
146
146
  );
147
147
 
148
148
  await pipeFileData(locked, file, packetSize, mtime);
@@ -30,7 +30,7 @@ export interface AdbSyncWritable {
30
30
  export async function adbSyncWriteRequest(
31
31
  writable: AdbSyncWritable,
32
32
  id: AdbSyncRequestId | string,
33
- value: number | string | Uint8Array
33
+ value: number | string | Uint8Array,
34
34
  ): Promise<void> {
35
35
  if (typeof value === "number") {
36
36
  const buffer = AdbSyncNumberRequest.serialize({
@@ -42,12 +42,12 @@ export async function adbSyncWriteRequest(
42
42
  // Let `writable` buffer writes
43
43
  const buffer = encodeUtf8(value);
44
44
  await writable.write(
45
- AdbSyncNumberRequest.serialize({ id, arg: buffer.byteLength })
45
+ AdbSyncNumberRequest.serialize({ id, arg: buffer.byteLength }),
46
46
  );
47
47
  await writable.write(buffer);
48
48
  } else {
49
49
  await writable.write(
50
- AdbSyncNumberRequest.serialize({ id, arg: value.byteLength })
50
+ AdbSyncNumberRequest.serialize({ id, arg: value.byteLength }),
51
51
  );
52
52
  await writable.write(value);
53
53
  }
@@ -19,17 +19,19 @@ export enum AdbSyncResponseId {
19
19
  Fail = "FAIL",
20
20
  }
21
21
 
22
+ export class AdbSyncError extends Error {}
23
+
22
24
  export const AdbSyncFailResponse = new Struct({ littleEndian: true })
23
25
  .uint32("messageLength")
24
26
  .string("message", { lengthField: "messageLength" })
25
27
  .postDeserialize((object) => {
26
- throw new Error(object.message);
28
+ throw new AdbSyncError(object.message);
27
29
  });
28
30
 
29
31
  export async function adbSyncReadResponse<T>(
30
32
  stream: AsyncExactReadable,
31
33
  id: AdbSyncResponseId,
32
- type: StructLike<T>
34
+ type: StructLike<T>,
33
35
  ): Promise<T> {
34
36
  const actualId = decodeUtf8(await stream.readExactly(4));
35
37
  switch (actualId) {
@@ -44,11 +46,11 @@ export async function adbSyncReadResponse<T>(
44
46
  }
45
47
 
46
48
  export async function* adbSyncReadResponses<
47
- T extends Struct<object, PropertyKey, object, any>
49
+ T extends Struct<object, PropertyKey, object, unknown>,
48
50
  >(
49
51
  stream: AsyncExactReadable,
50
52
  id: AdbSyncResponseId,
51
- type: T
53
+ type: T,
52
54
  ): AsyncGenerator<StructValueType<T>, void, void> {
53
55
  while (true) {
54
56
  const actualId = decodeUtf8(await stream.readExactly(4));
@@ -64,11 +66,11 @@ export async function* adbSyncReadResponses<
64
66
  await stream.readExactly(type.size);
65
67
  return;
66
68
  case id:
67
- yield await type.deserialize(stream);
69
+ yield (await type.deserialize(stream)) as StructValueType<T>;
68
70
  break;
69
71
  default:
70
72
  throw new Error(
71
- `Expected '${id}' or '${AdbSyncResponseId.Done}', but got '${actualId}'`
73
+ `Expected '${id}' or '${AdbSyncResponseId.Done}', but got '${actualId}'`,
72
74
  );
73
75
  }
74
76
  }
@@ -19,15 +19,15 @@ export class AdbSyncSocketLocked implements AsyncExactReadable {
19
19
  readonly #writeLock = new AutoResetEvent();
20
20
  readonly #combiner: BufferCombiner;
21
21
 
22
- public get position() {
22
+ get position() {
23
23
  return this.#readable.position;
24
24
  }
25
25
 
26
- public constructor(
26
+ constructor(
27
27
  writer: WritableStreamDefaultWriter<Consumable<Uint8Array>>,
28
28
  readable: BufferedReadableStream,
29
29
  bufferSize: number,
30
- lock: AutoResetEvent
30
+ lock: AutoResetEvent,
31
31
  ) {
32
32
  this.#writer = writer;
33
33
  this.#readable = readable;
@@ -35,42 +35,46 @@ export class AdbSyncSocketLocked implements AsyncExactReadable {
35
35
  this.#combiner = new BufferCombiner(bufferSize);
36
36
  }
37
37
 
38
- private async writeInnerStream(buffer: Uint8Array) {
38
+ async #writeInnerStream(buffer: Uint8Array) {
39
39
  await ConsumableWritableStream.write(this.#writer, buffer);
40
40
  }
41
41
 
42
- public async flush() {
42
+ async flush() {
43
43
  try {
44
44
  await this.#writeLock.wait();
45
45
  const buffer = this.#combiner.flush();
46
46
  if (buffer) {
47
- await this.writeInnerStream(buffer);
47
+ await this.#writeInnerStream(buffer);
48
48
  }
49
49
  } finally {
50
50
  this.#writeLock.notifyOne();
51
51
  }
52
52
  }
53
53
 
54
- public async write(data: Uint8Array) {
54
+ async write(data: Uint8Array) {
55
55
  try {
56
56
  await this.#writeLock.wait();
57
57
  for (const buffer of this.#combiner.push(data)) {
58
- await this.writeInnerStream(buffer);
58
+ await this.#writeInnerStream(buffer);
59
59
  }
60
60
  } finally {
61
61
  this.#writeLock.notifyOne();
62
62
  }
63
63
  }
64
64
 
65
- public async readExactly(length: number) {
65
+ async readExactly(length: number) {
66
66
  await this.flush();
67
67
  return await this.#readable.readExactly(length);
68
68
  }
69
69
 
70
- public release(): void {
70
+ release(): void {
71
71
  this.#combiner.flush();
72
72
  this.#socketLock.notifyOne();
73
73
  }
74
+
75
+ async close() {
76
+ await this.#readable.cancel();
77
+ }
74
78
  }
75
79
 
76
80
  export class AdbSyncSocket {
@@ -78,22 +82,23 @@ export class AdbSyncSocket {
78
82
  readonly #socket: AdbSocket;
79
83
  readonly #locked: AdbSyncSocketLocked;
80
84
 
81
- public constructor(socket: AdbSocket, bufferSize: number) {
85
+ constructor(socket: AdbSocket, bufferSize: number) {
82
86
  this.#socket = socket;
83
87
  this.#locked = new AdbSyncSocketLocked(
84
88
  socket.writable.getWriter(),
85
89
  new BufferedReadableStream(socket.readable),
86
90
  bufferSize,
87
- this.#lock
91
+ this.#lock,
88
92
  );
89
93
  }
90
94
 
91
- public async lock() {
95
+ async lock() {
92
96
  await this.#lock.wait();
93
97
  return this.#locked;
94
98
  }
95
99
 
96
- public async close() {
100
+ async close() {
101
+ await this.#locked.close();
97
102
  await this.#socket.close();
98
103
  }
99
104
  }
@@ -103,7 +103,7 @@ export type AdbSyncStatResponse =
103
103
  export async function adbSyncLstat(
104
104
  socket: AdbSyncSocket,
105
105
  path: string,
106
- v2: boolean
106
+ v2: boolean,
107
107
  ): Promise<AdbSyncStat> {
108
108
  const locked = await socket.lock();
109
109
  try {
@@ -112,14 +112,14 @@ export async function adbSyncLstat(
112
112
  return await adbSyncReadResponse(
113
113
  locked,
114
114
  AdbSyncResponseId.Lstat2,
115
- AdbSyncStatResponse
115
+ AdbSyncStatResponse,
116
116
  );
117
117
  } else {
118
118
  await adbSyncWriteRequest(locked, AdbSyncRequestId.Lstat, path);
119
119
  const response = await adbSyncReadResponse(
120
120
  locked,
121
121
  AdbSyncResponseId.Lstat,
122
- AdbSyncLstatResponse
122
+ AdbSyncLstatResponse,
123
123
  );
124
124
  return {
125
125
  mode: response.mode,
@@ -141,7 +141,7 @@ export async function adbSyncLstat(
141
141
 
142
142
  export async function adbSyncStat(
143
143
  socket: AdbSyncSocket,
144
- path: string
144
+ path: string,
145
145
  ): Promise<AdbSyncStatResponse> {
146
146
  const locked = await socket.lock();
147
147
  try {
@@ -149,7 +149,7 @@ export async function adbSyncStat(
149
149
  return await adbSyncReadResponse(
150
150
  locked,
151
151
  AdbSyncResponseId.Stat,
152
- AdbSyncStatResponse
152
+ AdbSyncStatResponse,
153
153
  );
154
154
  } finally {
155
155
  locked.release();