@yume-chan/adb 0.0.20 → 0.0.21

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 (115) hide show
  1. package/CHANGELOG.json +24 -0
  2. package/CHANGELOG.md +12 -1
  3. package/README.md +5 -3
  4. package/esm/adb.d.ts +4 -1
  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.map +1 -1
  26. package/esm/commands/subprocess/protocols/none.js.map +1 -1
  27. package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
  28. package/esm/commands/subprocess/protocols/shell.js +15 -15
  29. package/esm/commands/subprocess/protocols/shell.js.map +1 -1
  30. package/esm/commands/sync/push.js +1 -1
  31. package/esm/commands/sync/push.js.map +1 -1
  32. package/esm/commands/sync/request.js +1 -1
  33. package/esm/commands/sync/request.js.map +1 -1
  34. package/esm/commands/sync/response.d.ts +2 -0
  35. package/esm/commands/sync/response.d.ts.map +1 -1
  36. package/esm/commands/sync/response.js +4 -2
  37. package/esm/commands/sync/response.js.map +1 -1
  38. package/esm/commands/sync/socket.d.ts +0 -1
  39. package/esm/commands/sync/socket.d.ts.map +1 -1
  40. package/esm/commands/sync/socket.js +3 -3
  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 +15 -0
  45. package/esm/commands/sync/sync.d.ts.map +1 -1
  46. package/esm/commands/sync/sync.js +17 -2
  47. package/esm/commands/sync/sync.js.map +1 -1
  48. package/esm/commands/tcpip.d.ts.map +1 -1
  49. package/esm/commands/tcpip.js.map +1 -1
  50. package/esm/daemon/auth.d.ts +11 -9
  51. package/esm/daemon/auth.d.ts.map +1 -1
  52. package/esm/daemon/auth.js +21 -12
  53. package/esm/daemon/auth.js.map +1 -1
  54. package/esm/daemon/crypto.js +2 -2
  55. package/esm/daemon/crypto.js.map +1 -1
  56. package/esm/daemon/dispatcher.d.ts +4 -4
  57. package/esm/daemon/dispatcher.d.ts.map +1 -1
  58. package/esm/daemon/dispatcher.js +16 -16
  59. package/esm/daemon/dispatcher.js.map +1 -1
  60. package/esm/daemon/packet.js +1 -1
  61. package/esm/daemon/packet.js.map +1 -1
  62. package/esm/daemon/socket.d.ts +0 -2
  63. package/esm/daemon/socket.d.ts.map +1 -1
  64. package/esm/daemon/socket.js +12 -8
  65. package/esm/daemon/socket.js.map +1 -1
  66. package/esm/daemon/transport.d.ts +10 -2
  67. package/esm/daemon/transport.d.ts.map +1 -1
  68. package/esm/daemon/transport.js +5 -3
  69. package/esm/daemon/transport.js.map +1 -1
  70. package/esm/features.js +1 -1
  71. package/esm/features.js.map +1 -1
  72. package/esm/server/client.d.ts.map +1 -1
  73. package/esm/server/client.js +1 -2
  74. package/esm/server/client.js.map +1 -1
  75. package/esm/server/transport.d.ts.map +1 -1
  76. package/esm/server/transport.js.map +1 -1
  77. package/esm/utils/auto-reset-event.d.ts.map +1 -1
  78. package/esm/utils/auto-reset-event.js.map +1 -1
  79. package/esm/utils/conditional-variable.d.ts.map +1 -1
  80. package/esm/utils/conditional-variable.js.map +1 -1
  81. package/package.json +12 -13
  82. package/src/adb.ts +42 -30
  83. package/src/banner.ts +7 -7
  84. package/src/commands/base.ts +1 -1
  85. package/src/commands/framebuffer.ts +31 -3
  86. package/src/commands/power.ts +9 -9
  87. package/src/commands/reverse.ts +13 -13
  88. package/src/commands/subprocess/command.ts +24 -25
  89. package/src/commands/subprocess/protocols/none.ts +12 -12
  90. package/src/commands/subprocess/protocols/shell.ts +35 -35
  91. package/src/commands/sync/list.ts +5 -5
  92. package/src/commands/sync/pull.ts +4 -4
  93. package/src/commands/sync/push.ts +6 -6
  94. package/src/commands/sync/request.ts +3 -3
  95. package/src/commands/sync/response.ts +7 -5
  96. package/src/commands/sync/socket.ts +14 -14
  97. package/src/commands/sync/stat.ts +5 -5
  98. package/src/commands/sync/sync.ts +32 -17
  99. package/src/commands/tcpip.ts +2 -2
  100. package/src/daemon/auth.ts +49 -30
  101. package/src/daemon/crypto.ts +9 -9
  102. package/src/daemon/dispatcher.ts +40 -39
  103. package/src/daemon/packet.ts +1 -1
  104. package/src/daemon/socket.ts +34 -30
  105. package/src/daemon/transport.ts +32 -20
  106. package/src/server/client.ts +38 -41
  107. package/src/server/transport.ts +13 -13
  108. package/src/utils/auto-reset-event.ts +4 -4
  109. package/src/utils/base64.ts +5 -5
  110. package/src/utils/conditional-variable.ts +4 -4
  111. package/tsconfig.build.tsbuildinfo +1 -1
  112. package/esm/daemon/connection.d.ts +0 -11
  113. package/esm/daemon/connection.d.ts.map +0 -1
  114. package/esm/daemon/connection.js +0 -2
  115. package/esm/daemon/connection.js.map +0 -1
@@ -28,6 +28,10 @@ export interface AdbPacketDispatcherOptions {
28
28
  */
29
29
  appendNullToServiceString: boolean;
30
30
  maxPayloadSize: number;
31
+ /**
32
+ * Whether to preserve the connection open after the `AdbPacketDispatcher` is closed.
33
+ */
34
+ preserveConnection?: boolean | undefined;
31
35
  }
32
36
 
33
37
  /**
@@ -51,23 +55,23 @@ export class AdbPacketDispatcher implements Closeable {
51
55
 
52
56
  #writer: WritableStreamDefaultWriter<Consumable<AdbPacketInit>>;
53
57
 
54
- public readonly options: AdbPacketDispatcherOptions;
58
+ readonly options: AdbPacketDispatcherOptions;
55
59
 
56
60
  #closed = false;
57
61
  #disconnected = new PromiseResolver<void>();
58
- public get disconnected() {
62
+ get disconnected() {
59
63
  return this.#disconnected.promise;
60
64
  }
61
65
 
62
66
  #incomingSocketHandlers = new Map<string, AdbIncomingSocketHandler>();
63
67
  #readAbortController = new AbortController();
64
68
 
65
- public constructor(
69
+ constructor(
66
70
  connection: ReadableWritablePair<
67
71
  AdbPacketData,
68
72
  Consumable<AdbPacketInit>
69
73
  >,
70
- options: AdbPacketDispatcherOptions
74
+ options: AdbPacketDispatcherOptions,
71
75
  ) {
72
76
  this.options = options;
73
77
 
@@ -77,10 +81,10 @@ export class AdbPacketDispatcher implements Closeable {
77
81
  write: async (packet) => {
78
82
  switch (packet.command) {
79
83
  case AdbCommand.OK:
80
- this.handleOk(packet);
84
+ this.#handleOk(packet);
81
85
  break;
82
86
  case AdbCommand.Close:
83
- await this.handleClose(packet);
87
+ await this.#handleClose(packet);
84
88
  break;
85
89
  case AdbCommand.Write:
86
90
  if (this.#sockets.has(packet.arg1)) {
@@ -90,15 +94,15 @@ export class AdbPacketDispatcher implements Closeable {
90
94
  await this.sendPacket(
91
95
  AdbCommand.OK,
92
96
  packet.arg1,
93
- packet.arg0
97
+ packet.arg0,
94
98
  );
95
99
  break;
96
100
  }
97
101
  throw new Error(
98
- `Unknown local socket id: ${packet.arg1}`
102
+ `Unknown local socket id: ${packet.arg1}`,
99
103
  );
100
104
  case AdbCommand.Open:
101
- await this.handleOpen(packet);
105
+ await this.#handleOpen(packet);
102
106
  break;
103
107
  default:
104
108
  // Junk data may only appear in the authentication phase,
@@ -107,38 +111,33 @@ export class AdbPacketDispatcher implements Closeable {
107
111
  // (although it's possible that Adb added new commands in the future)
108
112
  throw new Error(
109
113
  `Unknown command: ${packet.command.toString(
110
- 16
111
- )}`
114
+ 16,
115
+ )}`,
112
116
  );
113
117
  }
114
118
  },
115
119
  }),
116
120
  {
117
- // There are multiple reasons for the pipe to stop,
118
- // (device disconnection, protocol error, or user abortion)
119
- // if the underlying streams are still open,
120
- // it's still possible to create another ADB connection.
121
- // So don't close `readable` here.
122
- preventCancel: true,
121
+ preventCancel: options.preserveConnection ?? false,
123
122
  signal: this.#readAbortController.signal,
124
- }
123
+ },
125
124
  )
126
125
  .then(
127
126
  () => {
128
- this.dispose();
127
+ this.#dispose();
129
128
  },
130
129
  (e) => {
131
130
  if (!this.#closed) {
132
131
  this.#disconnected.reject(e);
133
132
  }
134
- this.dispose();
135
- }
133
+ this.#dispose();
134
+ },
136
135
  );
137
136
 
138
137
  this.#writer = connection.writable.getWriter();
139
138
  }
140
139
 
141
- private handleOk(packet: AdbPacketData) {
140
+ #handleOk(packet: AdbPacketData) {
142
141
  if (this.#initializers.resolve(packet.arg1, packet.arg0)) {
143
142
  // Device successfully created the socket
144
143
  return;
@@ -156,13 +155,13 @@ export class AdbPacketDispatcher implements Closeable {
156
155
  void this.sendPacket(AdbCommand.Close, packet.arg1, packet.arg0);
157
156
  }
158
157
 
159
- private async handleClose(packet: AdbPacketData) {
158
+ async #handleClose(packet: AdbPacketData) {
160
159
  // If the socket is still pending
161
160
  if (
162
161
  packet.arg0 === 0 &&
163
162
  this.#initializers.reject(
164
163
  packet.arg1,
165
- new Error("Socket open failed")
164
+ new Error("Socket open failed"),
166
165
  )
167
166
  ) {
168
167
  // Device failed to create the socket
@@ -188,7 +187,7 @@ export class AdbPacketDispatcher implements Closeable {
188
187
  await this.sendPacket(
189
188
  AdbCommand.Close,
190
189
  packet.arg1,
191
- packet.arg0
190
+ packet.arg0,
192
191
  );
193
192
  }
194
193
  await socket.dispose();
@@ -201,22 +200,19 @@ export class AdbPacketDispatcher implements Closeable {
201
200
  // the device may also respond with two `CLSE` packets.
202
201
  }
203
202
 
204
- public addReverseTunnel(
205
- service: string,
206
- handler: AdbIncomingSocketHandler
207
- ) {
203
+ addReverseTunnel(service: string, handler: AdbIncomingSocketHandler) {
208
204
  this.#incomingSocketHandlers.set(service, handler);
209
205
  }
210
206
 
211
- public removeReverseTunnel(address: string) {
207
+ removeReverseTunnel(address: string) {
212
208
  this.#incomingSocketHandlers.delete(address);
213
209
  }
214
210
 
215
- public clearReverseTunnels() {
211
+ clearReverseTunnels() {
216
212
  this.#incomingSocketHandlers.clear();
217
213
  }
218
214
 
219
- private async handleOpen(packet: AdbPacketData) {
215
+ async #handleOpen(packet: AdbPacketData) {
220
216
  // `AsyncOperationManager` doesn't support skipping IDs
221
217
  // Use `add` + `resolve` to simulate this behavior
222
218
  const [localId] = this.#initializers.add<number>();
@@ -251,7 +247,7 @@ export class AdbPacketDispatcher implements Closeable {
251
247
  }
252
248
  }
253
249
 
254
- public async createSocket(service: string): Promise<AdbSocket> {
250
+ async createSocket(service: string): Promise<AdbSocket> {
255
251
  if (this.options.appendNullToServiceString) {
256
252
  service += "\0";
257
253
  }
@@ -273,11 +269,11 @@ export class AdbPacketDispatcher implements Closeable {
273
269
  return controller.socket;
274
270
  }
275
271
 
276
- public async sendPacket(
272
+ async sendPacket(
277
273
  command: AdbCommand,
278
274
  arg0: number,
279
275
  arg1: number,
280
- payload: string | Uint8Array = EMPTY_UINT8_ARRAY
276
+ payload: string | Uint8Array = EMPTY_UINT8_ARRAY,
281
277
  ): Promise<void> {
282
278
  if (typeof payload === "string") {
283
279
  payload = encodeUtf8(payload);
@@ -299,23 +295,28 @@ export class AdbPacketDispatcher implements Closeable {
299
295
  });
300
296
  }
301
297
 
302
- public async close() {
298
+ async close() {
303
299
  // Send `CLSE` packets for all sockets
304
300
  await Promise.all(
305
- Array.from(this.#sockets.values(), (socket) => socket.close())
301
+ Array.from(this.#sockets.values(), (socket) => socket.close()),
306
302
  );
307
303
 
308
304
  // Stop receiving
309
305
  // It's possible that we haven't received all `CLSE` confirm packets,
310
306
  // but it doesn't matter, the next connection can cope with them.
311
307
  this.#closed = true;
308
+
312
309
  this.#readAbortController.abort();
313
- this.#writer.releaseLock();
310
+ if (this.options.preserveConnection ?? false) {
311
+ this.#writer.releaseLock();
312
+ } else {
313
+ await this.#writer.close();
314
+ }
314
315
 
315
316
  // `pipe().then()` will call `dispose`
316
317
  }
317
318
 
318
- private dispose() {
319
+ #dispose() {
319
320
  for (const socket of this.#sockets.values()) {
320
321
  socket.dispose().catch(unreachable);
321
322
  }
@@ -53,7 +53,7 @@ export class AdbPacketSerializeStream extends ConsumableTransformStream<
53
53
  AdbPacketInit,
54
54
  Uint8Array
55
55
  > {
56
- public constructor() {
56
+ constructor() {
57
57
  const headerBuffer = new Uint8Array(AdbPacketHeader.size);
58
58
  super({
59
59
  transform: async (chunk, controller) => {
@@ -42,23 +42,23 @@ export class AdbDaemonSocketController
42
42
  Closeable,
43
43
  Disposable
44
44
  {
45
- private readonly dispatcher!: AdbPacketDispatcher;
45
+ readonly #dispatcher!: AdbPacketDispatcher;
46
46
 
47
- public readonly localId!: number;
48
- public readonly remoteId!: number;
49
- public readonly localCreated!: boolean;
50
- public readonly service!: string;
47
+ readonly localId!: number;
48
+ readonly remoteId!: number;
49
+ readonly localCreated!: boolean;
50
+ readonly service!: string;
51
51
 
52
52
  #duplex: DuplexStreamFactory<Uint8Array, Consumable<Uint8Array>>;
53
53
 
54
54
  #readable: ReadableStream<Uint8Array>;
55
55
  #readableController!: PushReadableStreamController<Uint8Array>;
56
- public get readable() {
56
+ get readable() {
57
57
  return this.#readable;
58
58
  }
59
59
 
60
60
  #writePromise: PromiseResolver<void> | undefined;
61
- public readonly writable: WritableStream<Consumable<Uint8Array>>;
61
+ readonly writable: WritableStream<Consumable<Uint8Array>>;
62
62
 
63
63
  #closed = false;
64
64
  /**
@@ -66,17 +66,21 @@ export class AdbDaemonSocketController
66
66
  *
67
67
  * It's only used by dispatcher to avoid sending another `CLSE` packet to remote.
68
68
  */
69
- public get closed() {
69
+ get closed() {
70
70
  return this.#closed;
71
71
  }
72
72
 
73
- private _socket: AdbDaemonSocket;
74
- public get socket() {
75
- return this._socket;
73
+ #socket: AdbDaemonSocket;
74
+ get socket() {
75
+ return this.#socket;
76
76
  }
77
77
 
78
- public constructor(options: AdbDaemonSocketConstructionOptions) {
79
- Object.assign(this, options);
78
+ constructor(options: AdbDaemonSocketConstructionOptions) {
79
+ this.#dispatcher = options.dispatcher;
80
+ this.localId = options.localId;
81
+ this.remoteId = options.remoteId;
82
+ this.localCreated = options.localCreated;
83
+ this.service = options.service;
80
84
 
81
85
  // Check this image to help you understand the stream graph
82
86
  // cspell: disable-next-line
@@ -89,7 +93,7 @@ export class AdbDaemonSocketController
89
93
  close: async () => {
90
94
  this.#closed = true;
91
95
 
92
- await this.dispatcher.sendPacket(
96
+ await this.#dispatcher.sendPacket(
93
97
  AdbCommand.Close,
94
98
  this.localId,
95
99
  this.remoteId
@@ -124,7 +128,7 @@ export class AdbDaemonSocketController
124
128
  write: async (chunk) => {
125
129
  // Wait for an ack packet
126
130
  this.#writePromise = new PromiseResolver();
127
- await this.dispatcher.sendPacket(
131
+ await this.#dispatcher.sendPacket(
128
132
  AdbCommand.Write,
129
133
  this.localId,
130
134
  this.remoteId,
@@ -134,13 +138,13 @@ export class AdbDaemonSocketController
134
138
  },
135
139
  })
136
140
  ),
137
- new DistributionStream(this.dispatcher.options.maxPayloadSize)
141
+ new DistributionStream(this.#dispatcher.options.maxPayloadSize)
138
142
  );
139
143
 
140
- this._socket = new AdbDaemonSocket(this);
144
+ this.#socket = new AdbDaemonSocket(this);
141
145
  }
142
146
 
143
- public async enqueue(data: Uint8Array) {
147
+ async enqueue(data: Uint8Array) {
144
148
  // Consumer may abort the `ReadableStream` to close the socket,
145
149
  // it's OK to throw away further packets in this case.
146
150
  if (this.#readableController.abortSignal.aborted) {
@@ -150,15 +154,15 @@ export class AdbDaemonSocketController
150
154
  await this.#readableController.enqueue(data);
151
155
  }
152
156
 
153
- public ack() {
157
+ ack() {
154
158
  this.#writePromise?.resolve();
155
159
  }
156
160
 
157
- public async close(): Promise<void> {
161
+ async close(): Promise<void> {
158
162
  await this.#duplex.close();
159
163
  }
160
164
 
161
- public dispose() {
165
+ dispose() {
162
166
  return this.#duplex.dispose();
163
167
  }
164
168
  }
@@ -178,35 +182,35 @@ export class AdbDaemonSocket
178
182
  {
179
183
  #controller: AdbDaemonSocketController;
180
184
 
181
- public get localId(): number {
185
+ get localId(): number {
182
186
  return this.#controller.localId;
183
187
  }
184
- public get remoteId(): number {
188
+ get remoteId(): number {
185
189
  return this.#controller.remoteId;
186
190
  }
187
- public get localCreated(): boolean {
191
+ get localCreated(): boolean {
188
192
  return this.#controller.localCreated;
189
193
  }
190
- public get service(): string {
194
+ get service(): string {
191
195
  return this.#controller.service;
192
196
  }
193
197
 
194
- public get readable(): ReadableStream<Uint8Array> {
198
+ get readable(): ReadableStream<Uint8Array> {
195
199
  return this.#controller.readable;
196
200
  }
197
- public get writable(): WritableStream<Consumable<Uint8Array>> {
201
+ get writable(): WritableStream<Consumable<Uint8Array>> {
198
202
  return this.#controller.writable;
199
203
  }
200
204
 
201
- public get closed(): boolean {
205
+ get closed(): boolean {
202
206
  return this.#controller.closed;
203
207
  }
204
208
 
205
- public constructor(controller: AdbDaemonSocketController) {
209
+ constructor(controller: AdbDaemonSocketController) {
206
210
  this.#controller = controller;
207
211
  }
208
212
 
209
- public close() {
213
+ close() {
210
214
  return this.#controller.close();
211
215
  }
212
216
  }
@@ -32,6 +32,10 @@ interface AdbDaemonAuthenticationOptions {
32
32
  connection: ReadableWritablePair<AdbPacketData, Consumable<AdbPacketInit>>;
33
33
  credentialStore: AdbCredentialStore;
34
34
  authenticators?: AdbAuthenticator[];
35
+ /**
36
+ * Whether to preserve the connection open after the `AdbDaemonTransport` is closed.
37
+ */
38
+ preserveConnection?: boolean | undefined;
35
39
  }
36
40
 
37
41
  interface AdbDaemonSocketConnectorConstructionOptions {
@@ -40,6 +44,10 @@ interface AdbDaemonSocketConnectorConstructionOptions {
40
44
  version: number;
41
45
  maxPayloadSize: number;
42
46
  banner: string;
47
+ /**
48
+ * Whether to preserve the connection open after the `AdbDaemonTransport` is closed.
49
+ */
50
+ preserveConnection?: boolean | undefined;
43
51
  }
44
52
 
45
53
  export class AdbDaemonTransport implements AdbTransport {
@@ -51,11 +59,12 @@ export class AdbDaemonTransport implements AdbTransport {
51
59
  * on the same connection. Because every time the device receives a `CNXN` packet,
52
60
  * it resets all internal state, and starts a new authentication process.
53
61
  */
54
- public static async authenticate({
62
+ static async authenticate({
55
63
  serial,
56
64
  connection,
57
65
  credentialStore,
58
66
  authenticators = ADB_DEFAULT_AUTHENTICATORS,
67
+ preserveConnection,
59
68
  }: AdbDaemonAuthenticationOptions): Promise<AdbDaemonTransport> {
60
69
  // Initially, set to highest-supported version and payload size.
61
70
  let version = 0x01000001;
@@ -65,7 +74,7 @@ export class AdbDaemonTransport implements AdbTransport {
65
74
  const resolver = new PromiseResolver<string>();
66
75
  const authProcessor = new AdbAuthenticationProcessor(
67
76
  authenticators,
68
- credentialStore
77
+ credentialStore,
69
78
  );
70
79
 
71
80
  // Here is similar to `AdbPacketDispatcher`,
@@ -80,13 +89,13 @@ export class AdbDaemonTransport implements AdbTransport {
80
89
  version = Math.min(version, packet.arg0);
81
90
  maxPayloadSize = Math.min(
82
91
  maxPayloadSize,
83
- packet.arg1
92
+ packet.arg1,
84
93
  );
85
94
  resolver.resolve(decodeUtf8(packet.payload));
86
95
  break;
87
96
  case AdbCommand.Auth: {
88
97
  const response = await authProcessor.process(
89
- packet
98
+ packet,
90
99
  );
91
100
  await sendPacket(response);
92
101
  break;
@@ -105,19 +114,19 @@ export class AdbDaemonTransport implements AdbTransport {
105
114
  // Don't cancel the source ReadableStream on AbortSignal abort.
106
115
  preventCancel: true,
107
116
  signal: abortController.signal,
108
- }
117
+ },
109
118
  )
110
119
  .then(
111
120
  () => {
112
121
  if (resolver.state === "running") {
113
122
  resolver.reject(
114
- new Error("Connection closed unexpectedly")
123
+ new Error("Connection closed unexpectedly"),
115
124
  );
116
125
  }
117
126
  },
118
127
  (e) => {
119
128
  resolver.reject(e);
120
- }
129
+ },
121
130
  );
122
131
 
123
132
  const writer = connection.writable.getWriter();
@@ -147,7 +156,7 @@ export class AdbDaemonTransport implements AdbTransport {
147
156
  AdbFeature.AbbExec,
148
157
  "remount_shell",
149
158
  "track_app",
150
- "sendrecv_v2",
159
+ AdbFeature.SendReceiveV2,
151
160
  "sendrecv_v2_brotli",
152
161
  "sendrecv_v2_lz4",
153
162
  "sendrecv_v2_zstd",
@@ -180,41 +189,43 @@ export class AdbDaemonTransport implements AdbTransport {
180
189
  version,
181
190
  maxPayloadSize,
182
191
  banner,
192
+ preserveConnection,
183
193
  });
184
194
  }
185
195
 
186
196
  readonly #dispatcher: AdbPacketDispatcher;
187
197
 
188
198
  #serial: string;
189
- public get serial() {
199
+ get serial() {
190
200
  return this.#serial;
191
201
  }
192
202
 
193
203
  #protocolVersion: number;
194
- public get protocolVersion() {
204
+ get protocolVersion() {
195
205
  return this.#protocolVersion;
196
206
  }
197
207
 
198
208
  #maxPayloadSize: number;
199
- public get maxPayloadSize() {
209
+ get maxPayloadSize() {
200
210
  return this.#maxPayloadSize;
201
211
  }
202
212
 
203
213
  #banner: AdbBanner;
204
- public get banner() {
214
+ get banner() {
205
215
  return this.#banner;
206
216
  }
207
217
 
208
- public get disconnected() {
218
+ get disconnected() {
209
219
  return this.#dispatcher.disconnected;
210
220
  }
211
221
 
212
- public constructor({
222
+ constructor({
213
223
  serial,
214
224
  connection,
215
225
  version,
216
226
  maxPayloadSize,
217
227
  banner,
228
+ preserveConnection,
218
229
  }: AdbDaemonSocketConnectorConstructionOptions) {
219
230
  this.#serial = serial;
220
231
  this.#banner = AdbBanner.parse(banner);
@@ -233,19 +244,20 @@ export class AdbDaemonTransport implements AdbTransport {
233
244
  calculateChecksum,
234
245
  appendNullToServiceString,
235
246
  maxPayloadSize,
247
+ preserveConnection,
236
248
  });
237
249
 
238
250
  this.#protocolVersion = version;
239
251
  this.#maxPayloadSize = maxPayloadSize;
240
252
  }
241
253
 
242
- public connect(service: string): ValueOrPromise<AdbSocket> {
254
+ connect(service: string): ValueOrPromise<AdbSocket> {
243
255
  return this.#dispatcher.createSocket(service);
244
256
  }
245
257
 
246
- public addReverseTunnel(
258
+ addReverseTunnel(
247
259
  handler: AdbIncomingSocketHandler,
248
- address?: string
260
+ address?: string,
249
261
  ): string {
250
262
  if (!address) {
251
263
  const id = Math.random().toString().substring(2);
@@ -255,15 +267,15 @@ export class AdbDaemonTransport implements AdbTransport {
255
267
  return address;
256
268
  }
257
269
 
258
- public removeReverseTunnel(address: string): void {
270
+ removeReverseTunnel(address: string): void {
259
271
  this.#dispatcher.removeReverseTunnel(address);
260
272
  }
261
273
 
262
- public clearReverseTunnels(): void {
274
+ clearReverseTunnels(): void {
263
275
  this.#dispatcher.clearReverseTunnels();
264
276
  }
265
277
 
266
- public close(): ValueOrPromise<void> {
278
+ close(): ValueOrPromise<void> {
267
279
  return this.#dispatcher.close();
268
280
  }
269
281
  }