@yume-chan/adb 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +18 -0
- package/CHANGELOG.md +13 -1
- package/LICENSE +1 -1
- package/esm/adb.d.ts +13 -8
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +63 -38
- package/esm/adb.js.map +1 -1
- package/esm/auth.d.ts +4 -4
- package/esm/auth.d.ts.map +1 -1
- package/esm/auth.js +6 -6
- package/esm/auth.js.map +1 -1
- package/esm/backend.d.ts +3 -3
- package/esm/backend.d.ts.map +1 -1
- package/esm/commands/base.d.ts +2 -2
- package/esm/commands/base.d.ts.map +1 -1
- package/esm/commands/base.js +1 -1
- package/esm/commands/base.js.map +1 -1
- package/esm/commands/framebuffer.d.ts +22 -6
- package/esm/commands/framebuffer.d.ts.map +1 -1
- package/esm/commands/framebuffer.js +33 -45
- package/esm/commands/framebuffer.js.map +1 -1
- package/esm/commands/install.d.ts +2 -2
- package/esm/commands/install.d.ts.map +1 -1
- package/esm/commands/install.js +12 -5
- package/esm/commands/install.js.map +1 -1
- package/esm/commands/power.d.ts.map +1 -1
- package/esm/commands/power.js +13 -9
- package/esm/commands/power.js.map +1 -1
- package/esm/commands/reverse.d.ts +5 -5
- package/esm/commands/reverse.d.ts.map +1 -1
- package/esm/commands/reverse.js +20 -18
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/command.d.ts +52 -0
- package/esm/commands/subprocess/command.d.ts.map +1 -0
- package/esm/commands/subprocess/command.js +81 -0
- package/esm/commands/subprocess/command.js.map +1 -0
- package/esm/commands/subprocess/index.d.ts +1 -53
- package/esm/commands/subprocess/index.d.ts.map +1 -1
- package/esm/commands/subprocess/index.js +1 -85
- package/esm/commands/subprocess/index.js.map +1 -1
- package/esm/commands/subprocess/protocols/none.d.ts +5 -5
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/none.js +5 -3
- package/esm/commands/subprocess/protocols/none.js.map +1 -1
- package/esm/commands/subprocess/protocols/shell.d.ts +4 -4
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.js +28 -20
- package/esm/commands/subprocess/protocols/shell.js.map +1 -1
- package/esm/commands/subprocess/protocols/types.d.ts +7 -7
- package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
- package/esm/commands/sync/index.d.ts +1 -1
- package/esm/commands/sync/index.d.ts.map +1 -1
- package/esm/commands/sync/index.js +1 -1
- package/esm/commands/sync/index.js.map +1 -1
- package/esm/commands/sync/list.d.ts +7 -7
- package/esm/commands/sync/list.d.ts.map +1 -1
- package/esm/commands/sync/list.js +34 -50
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts +5 -4
- package/esm/commands/sync/pull.d.ts.map +1 -1
- package/esm/commands/sync/pull.js +21 -22
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.d.ts +4 -4
- package/esm/commands/sync/push.d.ts.map +1 -1
- package/esm/commands/sync/push.js +7 -11
- package/esm/commands/sync/push.js.map +1 -1
- package/esm/commands/sync/request.d.ts +4 -4
- package/esm/commands/sync/request.d.ts.map +1 -1
- package/esm/commands/sync/request.js +6 -6
- package/esm/commands/sync/request.js.map +1 -1
- package/esm/commands/sync/response.d.ts +5 -10
- package/esm/commands/sync/response.d.ts.map +1 -1
- package/esm/commands/sync/response.js +35 -26
- package/esm/commands/sync/response.js.map +1 -1
- package/esm/commands/sync/stat.d.ts +7 -7
- package/esm/commands/sync/stat.d.ts.map +1 -1
- package/esm/commands/sync/stat.js +48 -55
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +7 -7
- package/esm/commands/sync/sync.d.ts.map +1 -1
- package/esm/commands/sync/sync.js +25 -22
- package/esm/commands/sync/sync.js.map +1 -1
- package/esm/crypto.d.ts.map +1 -1
- package/esm/crypto.js +26 -16
- package/esm/crypto.js.map +1 -1
- package/esm/index.d.ts +9 -10
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +9 -10
- package/esm/index.js.map +1 -1
- package/esm/packet.d.ts +8 -8
- package/esm/packet.d.ts.map +1 -1
- package/esm/packet.js +14 -12
- package/esm/packet.js.map +1 -1
- package/esm/socket/dispatcher.d.ts +11 -6
- package/esm/socket/dispatcher.d.ts.map +1 -1
- package/esm/socket/dispatcher.js +28 -20
- package/esm/socket/dispatcher.js.map +1 -1
- package/esm/socket/index.d.ts +1 -1
- package/esm/socket/index.d.ts.map +1 -1
- package/esm/socket/index.js +1 -1
- package/esm/socket/index.js.map +1 -1
- package/esm/socket/socket.d.ts +5 -5
- package/esm/socket/socket.d.ts.map +1 -1
- package/esm/socket/socket.js +37 -17
- package/esm/socket/socket.js.map +1 -1
- package/esm/utils/auto-reset-event.d.ts +1 -1
- package/esm/utils/auto-reset-event.d.ts.map +1 -1
- package/esm/utils/auto-reset-event.js +2 -2
- package/esm/utils/base64.d.ts +23 -0
- package/esm/utils/base64.d.ts.map +1 -1
- package/esm/utils/base64.js +36 -29
- package/esm/utils/base64.js.map +1 -1
- package/package.json +19 -17
- package/src/adb.ts +140 -86
- package/src/auth.ts +27 -18
- package/src/backend.ts +7 -4
- package/src/commands/base.ts +3 -2
- package/src/commands/framebuffer.ts +48 -47
- package/src/commands/install.ts +20 -10
- package/src/commands/power.ts +14 -10
- package/src/commands/reverse.ts +53 -33
- package/src/commands/subprocess/command.ts +134 -0
- package/src/commands/subprocess/index.ts +1 -137
- package/src/commands/subprocess/protocols/none.ts +10 -6
- package/src/commands/subprocess/protocols/shell.ts +72 -39
- package/src/commands/subprocess/protocols/types.ts +12 -8
- package/src/commands/sync/index.ts +1 -1
- package/src/commands/sync/list.ts +63 -68
- package/src/commands/sync/pull.ts +53 -37
- package/src/commands/sync/push.ts +26 -15
- package/src/commands/sync/request.ts +20 -21
- package/src/commands/sync/response.ts +63 -53
- package/src/commands/sync/stat.ts +91 -90
- package/src/commands/sync/sync.ts +56 -34
- package/src/crypto.ts +61 -33
- package/src/features.ts +1 -1
- package/src/index.ts +9 -11
- package/src/packet.ts +40 -30
- package/src/socket/dispatcher.ts +119 -77
- package/src/socket/index.ts +1 -1
- package/src/socket/socket.ts +68 -26
- package/src/utils/auto-reset-event.ts +3 -3
- package/src/utils/base64.ts +75 -42
- package/tsconfig.build.json +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
- package/esm/stream/buffered.d.ts +0 -39
- package/esm/stream/buffered.d.ts.map +0 -1
- package/esm/stream/buffered.js +0 -143
- package/esm/stream/buffered.js.map +0 -1
- package/esm/stream/detect.d.ts +0 -2
- package/esm/stream/detect.d.ts.map +0 -1
- package/esm/stream/detect.js +0 -6
- package/esm/stream/detect.js.map +0 -1
- package/esm/stream/detect.native.d.ts +0 -240
- package/esm/stream/detect.native.d.ts.map +0 -1
- package/esm/stream/detect.native.js +0 -60
- package/esm/stream/detect.native.js.map +0 -1
- package/esm/stream/detect.polyfill.d.ts +0 -18
- package/esm/stream/detect.polyfill.d.ts.map +0 -1
- package/esm/stream/detect.polyfill.js +0 -4
- package/esm/stream/detect.polyfill.js.map +0 -1
- package/esm/stream/index.d.ts +0 -4
- package/esm/stream/index.d.ts.map +0 -1
- package/esm/stream/index.js +0 -4
- package/esm/stream/index.js.map +0 -1
- package/esm/stream/transform.d.ts +0 -124
- package/esm/stream/transform.d.ts.map +0 -1
- package/esm/stream/transform.js +0 -379
- package/esm/stream/transform.js.map +0 -1
- package/src/stream/buffered.ts +0 -168
- package/src/stream/detect.native.ts +0 -362
- package/src/stream/detect.polyfill.ts +0 -22
- package/src/stream/detect.ts +0 -7
- package/src/stream/index.ts +0 -3
- package/src/stream/transform.ts +0 -474
- package/tsconfig.test.json +0 -9
- package/web-streams-polyfill-4.0.0-beta.2.tgz +0 -0
|
@@ -1,11 +1,23 @@
|
|
|
1
|
-
import { PromiseResolver } from
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { PromiseResolver } from '@yume-chan/async';
|
|
2
|
+
import {
|
|
3
|
+
PushReadableStream,
|
|
4
|
+
StructDeserializeStream,
|
|
5
|
+
StructSerializeStream,
|
|
6
|
+
TransformStream,
|
|
7
|
+
WritableStream,
|
|
8
|
+
pipeFrom,
|
|
9
|
+
type PushReadableStreamController,
|
|
10
|
+
type ReadableStream,
|
|
11
|
+
type WritableStreamDefaultWriter,
|
|
12
|
+
} from "@yume-chan/stream-extra";
|
|
13
|
+
import Struct, { placeholder, type StructValueType } from '@yume-chan/struct';
|
|
14
|
+
|
|
15
|
+
import { type Adb } from "../../../adb.js";
|
|
16
|
+
import { AdbFeatures } from '../../../features.js';
|
|
17
|
+
import { type AdbSocket } from "../../../socket/index.js";
|
|
18
|
+
import { encodeUtf8 } from '../../../utils/index.js';
|
|
19
|
+
|
|
20
|
+
import { type AdbSubprocessProtocol } from "./types.js";
|
|
9
21
|
|
|
10
22
|
export enum AdbShellProtocolId {
|
|
11
23
|
Stdin,
|
|
@@ -55,15 +67,17 @@ class StdoutDeserializeStream extends TransformStream<AdbShellProtocolPacket, Ui
|
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
69
|
|
|
58
|
-
class MultiplexStream<T>{
|
|
70
|
+
class MultiplexStream<T> {
|
|
59
71
|
private _readable: PushReadableStream<T>;
|
|
60
72
|
private _readableController!: PushReadableStreamController<T>;
|
|
61
|
-
public get readable() {
|
|
73
|
+
public get readable() {
|
|
74
|
+
return this._readable;
|
|
75
|
+
}
|
|
62
76
|
|
|
63
77
|
private _activeCount = 0;
|
|
64
78
|
|
|
65
79
|
constructor() {
|
|
66
|
-
this._readable = new PushReadableStream(controller => {
|
|
80
|
+
this._readable = new PushReadableStream((controller) => {
|
|
67
81
|
this._readableController = controller;
|
|
68
82
|
});
|
|
69
83
|
}
|
|
@@ -76,13 +90,13 @@ class MultiplexStream<T>{
|
|
|
76
90
|
write: async (chunk) => {
|
|
77
91
|
await this._readableController.enqueue(chunk);
|
|
78
92
|
},
|
|
79
|
-
abort:
|
|
93
|
+
abort: () => {
|
|
80
94
|
this._activeCount -= 1;
|
|
81
95
|
if (this._activeCount === 0) {
|
|
82
96
|
this._readableController.close();
|
|
83
97
|
}
|
|
84
98
|
},
|
|
85
|
-
close:
|
|
99
|
+
close: () => {
|
|
86
100
|
this._activeCount -= 1;
|
|
87
101
|
if (this._activeCount === 0) {
|
|
88
102
|
this._readableController.close();
|
|
@@ -102,32 +116,44 @@ class MultiplexStream<T>{
|
|
|
102
116
|
*/
|
|
103
117
|
export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
104
118
|
public static isSupported(adb: Adb) {
|
|
105
|
-
return adb.features
|
|
119
|
+
return adb.features.includes(AdbFeatures.ShellV2);
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
public static async pty(adb: Adb, command: string) {
|
|
109
123
|
// TODO: AdbShellSubprocessProtocol: Support setting `XTERM` environment variable
|
|
110
|
-
return new AdbSubprocessShellProtocol(
|
|
124
|
+
return new AdbSubprocessShellProtocol(
|
|
125
|
+
await adb.createSocket(`shell,v2,pty:${command}`)
|
|
126
|
+
);
|
|
111
127
|
}
|
|
112
128
|
|
|
113
129
|
public static async raw(adb: Adb, command: string) {
|
|
114
|
-
return new AdbSubprocessShellProtocol(
|
|
130
|
+
return new AdbSubprocessShellProtocol(
|
|
131
|
+
await adb.createSocket(`shell,v2,raw:${command}`)
|
|
132
|
+
);
|
|
115
133
|
}
|
|
116
134
|
|
|
117
135
|
private readonly _socket: AdbSocket;
|
|
118
136
|
private _socketWriter: WritableStreamDefaultWriter<AdbShellProtocolPacketInit>;
|
|
119
137
|
|
|
120
138
|
private _stdin: WritableStream<Uint8Array>;
|
|
121
|
-
public get stdin() {
|
|
139
|
+
public get stdin() {
|
|
140
|
+
return this._stdin;
|
|
141
|
+
}
|
|
122
142
|
|
|
123
143
|
private _stdout: ReadableStream<Uint8Array>;
|
|
124
|
-
public get stdout() {
|
|
144
|
+
public get stdout() {
|
|
145
|
+
return this._stdout;
|
|
146
|
+
}
|
|
125
147
|
|
|
126
148
|
private _stderr: ReadableStream<Uint8Array>;
|
|
127
|
-
public get stderr() {
|
|
149
|
+
public get stderr() {
|
|
150
|
+
return this._stderr;
|
|
151
|
+
}
|
|
128
152
|
|
|
129
153
|
private readonly _exit = new PromiseResolver<number>();
|
|
130
|
-
public get exit() {
|
|
154
|
+
public get exit() {
|
|
155
|
+
return this._exit.promise;
|
|
156
|
+
}
|
|
131
157
|
|
|
132
158
|
public constructor(socket: AdbSocket) {
|
|
133
159
|
this._socket = socket;
|
|
@@ -140,27 +166,34 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
140
166
|
|
|
141
167
|
const [stdout, stderr] = socket.readable
|
|
142
168
|
.pipeThrough(new StructDeserializeStream(AdbShellProtocolPacket))
|
|
143
|
-
.pipeThrough(
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
169
|
+
.pipeThrough(
|
|
170
|
+
new TransformStream<
|
|
171
|
+
AdbShellProtocolPacket,
|
|
172
|
+
AdbShellProtocolPacket
|
|
173
|
+
>({
|
|
174
|
+
transform: (chunk, controller) => {
|
|
175
|
+
if (chunk.id === AdbShellProtocolId.Exit) {
|
|
176
|
+
this._exit.resolve(new Uint8Array(chunk.data)[0]!);
|
|
177
|
+
// We can let `StdoutDeserializeStream` to process `AdbShellProtocolId.Exit`,
|
|
178
|
+
// but since we need this `TransformStream` to capture the exit code anyway,
|
|
179
|
+
// terminating child streams here is killing two birds with one stone.
|
|
180
|
+
controller.terminate();
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
controller.enqueue(chunk);
|
|
184
|
+
},
|
|
185
|
+
})
|
|
186
|
+
)
|
|
156
187
|
.tee();
|
|
157
|
-
this._stdout = stdout
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
188
|
+
this._stdout = stdout.pipeThrough(
|
|
189
|
+
new StdoutDeserializeStream(AdbShellProtocolId.Stdout)
|
|
190
|
+
);
|
|
191
|
+
this._stderr = stderr.pipeThrough(
|
|
192
|
+
new StdoutDeserializeStream(AdbShellProtocolId.Stderr)
|
|
193
|
+
);
|
|
161
194
|
|
|
162
195
|
const multiplexer = new MultiplexStream<AdbShellProtocolPacketInit>();
|
|
163
|
-
multiplexer.readable
|
|
196
|
+
void multiplexer.readable
|
|
164
197
|
.pipeThrough(new StructSerializeStream(AdbShellProtocolPacket))
|
|
165
198
|
.pipeTo(socket.writable);
|
|
166
199
|
|
|
@@ -178,7 +211,7 @@ export class AdbSubprocessShellProtocol implements AdbSubprocessProtocol {
|
|
|
178
211
|
data: encodeUtf8(
|
|
179
212
|
// The "correct" format is `${rows}x${cols},${x_pixels}x${y_pixels}`
|
|
180
213
|
// However, according to https://linux.die.net/man/4/tty_ioctl
|
|
181
|
-
// `x_pixels` and `y_pixels` are
|
|
214
|
+
// `x_pixels` and `y_pixels` are unused, so always sending `0` should be fine.
|
|
182
215
|
`${rows}x${cols},0x0\0`
|
|
183
216
|
),
|
|
184
217
|
});
|
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
type ReadableStream,
|
|
3
|
+
type WritableStream,
|
|
4
|
+
} from "@yume-chan/stream-extra";
|
|
5
|
+
import { type ValueOrPromise } from "@yume-chan/struct";
|
|
6
|
+
|
|
7
|
+
import { type Adb } from "../../../adb.js";
|
|
8
|
+
import { type AdbSocket } from "../../../socket/index.js";
|
|
5
9
|
|
|
6
10
|
export interface AdbSubprocessProtocol {
|
|
7
11
|
/**
|
|
8
|
-
* A WritableStream that writes to the `stdin`
|
|
12
|
+
* A WritableStream that writes to the `stdin` stream.
|
|
9
13
|
*/
|
|
10
14
|
readonly stdin: WritableStream<Uint8Array>;
|
|
11
15
|
|
|
12
16
|
/**
|
|
13
|
-
* The `stdout`
|
|
17
|
+
* The `stdout` stream of the process.
|
|
14
18
|
*/
|
|
15
19
|
readonly stdout: ReadableStream<Uint8Array>;
|
|
16
20
|
|
|
17
21
|
/**
|
|
18
|
-
* The `stderr`
|
|
22
|
+
* The `stderr` stream of the process.
|
|
19
23
|
*
|
|
20
24
|
* Note: Some `AdbSubprocessProtocol` doesn't separate `stdout` and `stderr`,
|
|
21
25
|
* All output will be sent to `stdout`.
|
|
@@ -55,5 +59,5 @@ export interface AdbSubprocessProtocolConstructor {
|
|
|
55
59
|
raw(adb: Adb, command: string): ValueOrPromise<AdbSubprocessProtocol>;
|
|
56
60
|
|
|
57
61
|
/** Creates a new `AdbShell` by attaching to an exist `AdbSocket` */
|
|
58
|
-
new(socket: AdbSocket): AdbSubprocessProtocol;
|
|
62
|
+
new (socket: AdbSocket): AdbSubprocessProtocol;
|
|
59
63
|
}
|
|
@@ -1,86 +1,81 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
type BufferedReadableStream,
|
|
3
|
+
type WritableStreamDefaultWriter,
|
|
4
|
+
} from "@yume-chan/stream-extra";
|
|
5
|
+
import Struct from "@yume-chan/struct";
|
|
6
|
+
|
|
7
|
+
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
8
|
+
import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
|
|
9
|
+
import {
|
|
10
|
+
AdbSyncLstatResponse,
|
|
11
|
+
AdbSyncStatResponse,
|
|
12
|
+
type AdbSyncStat,
|
|
13
|
+
} from "./stat.js";
|
|
6
14
|
|
|
7
15
|
export interface AdbSyncEntry extends AdbSyncStat {
|
|
8
16
|
name: string;
|
|
9
17
|
}
|
|
10
18
|
|
|
11
|
-
export const AdbSyncEntryResponse =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
.extra({ id: AdbSyncResponseId.Entry as const });
|
|
17
|
-
|
|
18
|
-
export type AdbSyncEntryResponse = typeof AdbSyncEntryResponse['TDeserializeResult'];
|
|
19
|
+
export const AdbSyncEntryResponse = new Struct({ littleEndian: true })
|
|
20
|
+
.fields(AdbSyncLstatResponse)
|
|
21
|
+
.uint32("nameLength")
|
|
22
|
+
.string("name", { lengthField: "nameLength" })
|
|
23
|
+
.extra({ id: AdbSyncResponseId.Entry as const });
|
|
19
24
|
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
.fields(AdbSyncStatResponse)
|
|
23
|
-
.uint32('nameLength')
|
|
24
|
-
.string('name', { lengthField: 'nameLength' })
|
|
25
|
-
.extra({ id: AdbSyncResponseId.Entry2 as const });
|
|
25
|
+
export type AdbSyncEntryResponse =
|
|
26
|
+
typeof AdbSyncEntryResponse["TDeserializeResult"];
|
|
26
27
|
|
|
27
|
-
export
|
|
28
|
+
export const AdbSyncEntry2Response = new Struct({ littleEndian: true })
|
|
29
|
+
.fields(AdbSyncStatResponse)
|
|
30
|
+
.uint32("nameLength")
|
|
31
|
+
.string("name", { lengthField: "nameLength" })
|
|
32
|
+
.extra({ id: AdbSyncResponseId.Entry2 as const });
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
[
|
|
31
|
-
[AdbSyncResponseId.Done]: new AdbSyncDoneResponse(AdbSyncEntryResponse.size),
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
const LIST_V2_RESPONSE_TYPES = {
|
|
35
|
-
[AdbSyncResponseId.Entry2]: AdbSyncEntry2Response,
|
|
36
|
-
[AdbSyncResponseId.Done]: new AdbSyncDoneResponse(AdbSyncEntry2Response.size),
|
|
37
|
-
};
|
|
34
|
+
export type AdbSyncEntry2Response =
|
|
35
|
+
typeof AdbSyncEntry2Response["TDeserializeResult"];
|
|
38
36
|
|
|
39
37
|
export async function* adbSyncOpenDir(
|
|
40
|
-
stream:
|
|
38
|
+
stream: BufferedReadableStream,
|
|
41
39
|
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
42
40
|
path: string,
|
|
43
|
-
v2: boolean
|
|
41
|
+
v2: boolean
|
|
44
42
|
): AsyncGenerator<AdbSyncEntry, void, void> {
|
|
45
|
-
let requestId: AdbSyncRequestId.List | AdbSyncRequestId.List2;
|
|
46
|
-
let responseType: typeof LIST_V1_RESPONSE_TYPES | typeof LIST_V2_RESPONSE_TYPES;
|
|
47
|
-
|
|
48
43
|
if (v2) {
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
await adbSyncWriteRequest(writer, AdbSyncRequestId.List2, path);
|
|
45
|
+
for await (const item of adbSyncReadResponses(
|
|
46
|
+
stream,
|
|
47
|
+
AdbSyncResponseId.Entry2,
|
|
48
|
+
AdbSyncEntry2Response
|
|
49
|
+
)) {
|
|
50
|
+
// `LST2` can return error codes for failed `lstat` calls.
|
|
51
|
+
// `LIST` just ignores them.
|
|
52
|
+
// But they only contain `name` so still pretty useless.
|
|
53
|
+
if (item.error !== 0) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
yield item;
|
|
57
|
+
}
|
|
51
58
|
} else {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// `LST2` can return error codes for failed `lstat` calls.
|
|
73
|
-
// `LIST` just ignores them.
|
|
74
|
-
// But they only contain `name` so still pretty useless.
|
|
75
|
-
if (response.error !== 0) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
yield response;
|
|
79
|
-
break;
|
|
80
|
-
case AdbSyncResponseId.Done:
|
|
81
|
-
return;
|
|
82
|
-
default:
|
|
83
|
-
throw new Error('Unexpected response id');
|
|
59
|
+
await adbSyncWriteRequest(writer, AdbSyncRequestId.List, path);
|
|
60
|
+
for await (const item of adbSyncReadResponses(
|
|
61
|
+
stream,
|
|
62
|
+
AdbSyncResponseId.Entry,
|
|
63
|
+
AdbSyncEntryResponse
|
|
64
|
+
)) {
|
|
65
|
+
// Convert to same format as `AdbSyncEntry2Response` for easier consumption.
|
|
66
|
+
// However it will add some overhead.
|
|
67
|
+
yield {
|
|
68
|
+
mode: item.mode,
|
|
69
|
+
size: BigInt(item.size),
|
|
70
|
+
mtime: BigInt(item.mtime),
|
|
71
|
+
get type() {
|
|
72
|
+
return item.type;
|
|
73
|
+
},
|
|
74
|
+
get permission() {
|
|
75
|
+
return item.permission;
|
|
76
|
+
},
|
|
77
|
+
name: item.name,
|
|
78
|
+
};
|
|
84
79
|
}
|
|
85
80
|
}
|
|
86
81
|
}
|
|
@@ -1,46 +1,62 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
ReadableStream,
|
|
3
|
+
type BufferedReadableStream,
|
|
4
|
+
type WritableStreamDefaultWriter,
|
|
5
|
+
} from "@yume-chan/stream-extra";
|
|
6
|
+
import Struct from "@yume-chan/struct";
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
.uint32('dataLength')
|
|
9
|
-
.uint8Array('data', { lengthField: 'dataLength' })
|
|
10
|
-
.extra({ id: AdbSyncResponseId.Data as const });
|
|
8
|
+
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
9
|
+
import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
|
|
11
10
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
11
|
+
export const AdbSyncDataResponse = new Struct({ littleEndian: true })
|
|
12
|
+
.uint32("dataLength")
|
|
13
|
+
.uint8Array("data", { lengthField: "dataLength" })
|
|
14
|
+
.extra({ id: AdbSyncResponseId.Data as const });
|
|
15
|
+
|
|
16
|
+
export type AdbSyncDataResponse =
|
|
17
|
+
typeof AdbSyncDataResponse["TDeserializeResult"];
|
|
16
18
|
|
|
17
19
|
export function adbSyncPull(
|
|
18
|
-
stream:
|
|
20
|
+
stream: BufferedReadableStream,
|
|
19
21
|
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
20
|
-
path: string
|
|
22
|
+
path: string
|
|
21
23
|
): ReadableStream<Uint8Array> {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
let generator!: AsyncGenerator<AdbSyncDataResponse, void, void>;
|
|
25
|
+
return new ReadableStream<Uint8Array>(
|
|
26
|
+
{
|
|
27
|
+
async start() {
|
|
28
|
+
// TODO: If `ReadableStream.from(AsyncGenerator)` is added to spec, use it instead.
|
|
29
|
+
await adbSyncWriteRequest(
|
|
30
|
+
writer,
|
|
31
|
+
AdbSyncRequestId.Receive,
|
|
32
|
+
path
|
|
33
|
+
);
|
|
34
|
+
generator = adbSyncReadResponses(
|
|
35
|
+
stream,
|
|
36
|
+
AdbSyncResponseId.Data,
|
|
37
|
+
AdbSyncDataResponse
|
|
38
|
+
);
|
|
39
|
+
},
|
|
40
|
+
async pull(controller) {
|
|
41
|
+
const { done, value } = await generator.next();
|
|
42
|
+
if (done) {
|
|
33
43
|
controller.close();
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
controller.enqueue(value.data);
|
|
47
|
+
},
|
|
48
|
+
cancel() {
|
|
49
|
+
generator.return().catch((e) => {
|
|
50
|
+
void e;
|
|
51
|
+
});
|
|
52
|
+
throw new Error(`Sync commands can't be canceled.`);
|
|
53
|
+
},
|
|
41
54
|
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
{
|
|
56
|
+
highWaterMark: 16 * 1024,
|
|
57
|
+
size(chunk) {
|
|
58
|
+
return chunk.byteLength;
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
);
|
|
46
62
|
}
|
|
@@ -1,39 +1,50 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {
|
|
2
|
+
ChunkStream,
|
|
3
|
+
WritableStream,
|
|
4
|
+
pipeFrom,
|
|
5
|
+
type BufferedReadableStream,
|
|
6
|
+
type WritableStreamDefaultWriter,
|
|
7
|
+
} from "@yume-chan/stream-extra";
|
|
8
|
+
import Struct from "@yume-chan/struct";
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
11
|
+
import { AdbSyncResponseId, adbSyncReadResponse } from "./response.js";
|
|
12
|
+
import { LinuxFileType } from "./stat.js";
|
|
10
13
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
export const AdbSyncOkResponse = new Struct({ littleEndian: true }).uint32(
|
|
15
|
+
"unused"
|
|
16
|
+
);
|
|
14
17
|
|
|
15
18
|
export const ADB_SYNC_MAX_PACKET_SIZE = 64 * 1024;
|
|
16
19
|
|
|
17
20
|
export function adbSyncPush(
|
|
18
|
-
stream:
|
|
21
|
+
stream: BufferedReadableStream,
|
|
19
22
|
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
20
23
|
filename: string,
|
|
21
24
|
mode: number = (LinuxFileType.File << 12) | 0o666,
|
|
22
25
|
mtime: number = (Date.now() / 1000) | 0,
|
|
23
|
-
packetSize: number = ADB_SYNC_MAX_PACKET_SIZE
|
|
26
|
+
packetSize: number = ADB_SYNC_MAX_PACKET_SIZE
|
|
24
27
|
): WritableStream<Uint8Array> {
|
|
25
28
|
return pipeFrom(
|
|
26
29
|
new WritableStream<Uint8Array>({
|
|
27
30
|
async start() {
|
|
28
31
|
const pathAndMode = `${filename},${mode.toString()}`;
|
|
29
|
-
await adbSyncWriteRequest(
|
|
32
|
+
await adbSyncWriteRequest(
|
|
33
|
+
writer,
|
|
34
|
+
AdbSyncRequestId.Send,
|
|
35
|
+
pathAndMode
|
|
36
|
+
);
|
|
30
37
|
},
|
|
31
38
|
async write(chunk) {
|
|
32
39
|
await adbSyncWriteRequest(writer, AdbSyncRequestId.Data, chunk);
|
|
33
40
|
},
|
|
34
41
|
async close() {
|
|
35
42
|
await adbSyncWriteRequest(writer, AdbSyncRequestId.Done, mtime);
|
|
36
|
-
await adbSyncReadResponse(
|
|
43
|
+
await adbSyncReadResponse(
|
|
44
|
+
stream,
|
|
45
|
+
AdbSyncResponseId.Ok,
|
|
46
|
+
AdbSyncOkResponse
|
|
47
|
+
);
|
|
37
48
|
},
|
|
38
49
|
}),
|
|
39
50
|
new ChunkStream(packetSize)
|
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { type WritableStreamDefaultWriter } from "@yume-chan/stream-extra";
|
|
2
|
+
import Struct from "@yume-chan/struct";
|
|
3
|
+
|
|
3
4
|
import { encodeUtf8 } from "../../utils/index.js";
|
|
4
5
|
|
|
5
6
|
export enum AdbSyncRequestId {
|
|
6
|
-
List =
|
|
7
|
-
List2 =
|
|
8
|
-
Send =
|
|
9
|
-
Lstat =
|
|
10
|
-
Stat =
|
|
11
|
-
Lstat2 =
|
|
12
|
-
Data =
|
|
13
|
-
Done =
|
|
14
|
-
Receive =
|
|
7
|
+
List = "LIST",
|
|
8
|
+
List2 = "LIS2",
|
|
9
|
+
Send = "SEND",
|
|
10
|
+
Lstat = "STAT",
|
|
11
|
+
Stat = "STA2",
|
|
12
|
+
Lstat2 = "LST2",
|
|
13
|
+
Data = "DATA",
|
|
14
|
+
Done = "DONE",
|
|
15
|
+
Receive = "RECV",
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export const AdbSyncNumberRequest =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.uint32('arg');
|
|
18
|
+
export const AdbSyncNumberRequest = new Struct({ littleEndian: true })
|
|
19
|
+
.string("id", { length: 4 })
|
|
20
|
+
.uint32("arg");
|
|
21
21
|
|
|
22
|
-
export const AdbSyncDataRequest =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.uint8Array('data', { lengthField: 'arg' });
|
|
22
|
+
export const AdbSyncDataRequest = new Struct({ littleEndian: true })
|
|
23
|
+
.fields(AdbSyncNumberRequest)
|
|
24
|
+
.uint8Array("data", { lengthField: "arg" });
|
|
26
25
|
|
|
27
26
|
export async function adbSyncWriteRequest(
|
|
28
27
|
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
@@ -30,12 +29,12 @@ export async function adbSyncWriteRequest(
|
|
|
30
29
|
value: number | string | Uint8Array
|
|
31
30
|
): Promise<void> {
|
|
32
31
|
let buffer: Uint8Array;
|
|
33
|
-
if (typeof value ===
|
|
32
|
+
if (typeof value === "number") {
|
|
34
33
|
buffer = AdbSyncNumberRequest.serialize({
|
|
35
34
|
id,
|
|
36
35
|
arg: value,
|
|
37
36
|
});
|
|
38
|
-
} else if (typeof value ===
|
|
37
|
+
} else if (typeof value === "string") {
|
|
39
38
|
buffer = AdbSyncDataRequest.serialize({
|
|
40
39
|
id,
|
|
41
40
|
data: encodeUtf8(value),
|