@yume-chan/adb 0.0.18 → 0.0.19
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 +21 -0
- package/CHANGELOG.md +11 -1
- package/esm/adb.d.ts +63 -60
- package/esm/adb.d.ts.map +1 -1
- package/esm/adb.js +257 -249
- package/esm/adb.js.map +1 -1
- package/esm/auth.d.ts +51 -51
- package/esm/auth.d.ts.map +1 -1
- package/esm/auth.js +95 -96
- package/esm/auth.js.map +1 -1
- package/esm/backend.d.ts +8 -8
- package/esm/backend.d.ts.map +1 -1
- package/esm/backend.js +1 -1
- package/esm/commands/base.d.ts +6 -6
- package/esm/commands/base.d.ts.map +1 -1
- package/esm/commands/base.js +8 -8
- package/esm/commands/framebuffer.d.ts +53 -53
- package/esm/commands/framebuffer.d.ts.map +1 -1
- package/esm/commands/framebuffer.js +46 -46
- package/esm/commands/framebuffer.js.map +1 -1
- package/esm/commands/index.d.ts +7 -8
- package/esm/commands/index.d.ts.map +1 -1
- package/esm/commands/index.js +7 -8
- package/esm/commands/index.js.map +1 -1
- package/esm/commands/install.d.ts +9 -3
- package/esm/commands/install.d.ts.map +1 -1
- package/esm/commands/install.js +26 -26
- package/esm/commands/install.js.map +1 -1
- package/esm/commands/power.d.ts +22 -22
- package/esm/commands/power.js +48 -48
- package/esm/commands/reverse.d.ts +41 -28
- package/esm/commands/reverse.d.ts.map +1 -1
- package/esm/commands/reverse.js +125 -100
- package/esm/commands/reverse.js.map +1 -1
- package/esm/commands/subprocess/command.d.ts +57 -51
- package/esm/commands/subprocess/command.d.ts.map +1 -1
- package/esm/commands/subprocess/command.js +86 -80
- package/esm/commands/subprocess/command.js.map +1 -1
- package/esm/commands/subprocess/index.d.ts +3 -3
- package/esm/commands/subprocess/index.js +3 -3
- package/esm/commands/subprocess/protocols/index.d.ts +3 -3
- package/esm/commands/subprocess/protocols/index.js +3 -3
- package/esm/commands/subprocess/protocols/none.d.ts +35 -35
- package/esm/commands/subprocess/protocols/none.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/none.js +65 -55
- package/esm/commands/subprocess/protocols/none.js.map +1 -1
- package/esm/commands/subprocess/protocols/shell.d.ts +39 -38
- package/esm/commands/subprocess/protocols/shell.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/shell.js +166 -162
- package/esm/commands/subprocess/protocols/shell.js.map +1 -1
- package/esm/commands/subprocess/protocols/types.d.ts +49 -49
- package/esm/commands/subprocess/protocols/types.d.ts.map +1 -1
- package/esm/commands/subprocess/protocols/types.js +1 -1
- package/esm/commands/subprocess/utils.d.ts +1 -1
- package/esm/commands/subprocess/utils.js +18 -18
- package/esm/commands/sync/index.d.ts +8 -7
- package/esm/commands/sync/index.d.ts.map +1 -1
- package/esm/commands/sync/index.js +8 -7
- package/esm/commands/sync/index.js.map +1 -1
- package/esm/commands/sync/list.d.ts +42 -40
- package/esm/commands/sync/list.d.ts.map +1 -1
- package/esm/commands/sync/list.js +67 -47
- package/esm/commands/sync/list.js.map +1 -1
- package/esm/commands/sync/pull.d.ts +13 -11
- package/esm/commands/sync/pull.d.ts.map +1 -1
- package/esm/commands/sync/pull.js +35 -37
- package/esm/commands/sync/pull.js.map +1 -1
- package/esm/commands/sync/push.d.ts +46 -7
- package/esm/commands/sync/push.d.ts.map +1 -1
- package/esm/commands/sync/push.js +89 -22
- package/esm/commands/sync/push.js.map +1 -1
- package/esm/commands/sync/request.d.ts +26 -23
- package/esm/commands/sync/request.d.ts.map +1 -1
- package/esm/commands/sync/request.js +40 -42
- package/esm/commands/sync/request.js.map +1 -1
- package/esm/commands/sync/response.d.ts +19 -19
- package/esm/commands/sync/response.d.ts.map +1 -1
- package/esm/commands/sync/response.js +54 -54
- package/esm/commands/sync/response.js.map +1 -1
- package/esm/commands/sync/socket.d.ts +27 -0
- package/esm/commands/sync/socket.d.ts.map +1 -0
- package/esm/commands/sync/socket.js +66 -0
- package/esm/commands/sync/socket.js.map +1 -0
- package/esm/commands/sync/stat.d.ts +72 -72
- package/esm/commands/sync/stat.d.ts.map +1 -1
- package/esm/commands/sync/stat.js +116 -104
- package/esm/commands/sync/stat.js.map +1 -1
- package/esm/commands/sync/sync.d.ts +72 -60
- package/esm/commands/sync/sync.d.ts.map +1 -1
- package/esm/commands/sync/sync.js +127 -149
- package/esm/commands/sync/sync.js.map +1 -1
- package/esm/commands/tcpip.d.ts +5 -5
- package/esm/commands/tcpip.js +18 -18
- package/esm/crypto.d.ts +36 -36
- package/esm/crypto.js +248 -248
- package/esm/features.d.ts +10 -7
- package/esm/features.d.ts.map +1 -1
- package/esm/features.js +13 -10
- package/esm/features.js.map +1 -1
- package/esm/index.d.ts +9 -9
- package/esm/index.js +9 -9
- package/esm/packet.d.ts +45 -46
- package/esm/packet.d.ts.map +1 -1
- package/esm/packet.js +43 -48
- package/esm/packet.js.map +1 -1
- package/esm/socket/dispatcher.d.ts +59 -59
- package/esm/socket/dispatcher.d.ts.map +1 -1
- package/esm/socket/dispatcher.js +223 -234
- package/esm/socket/dispatcher.js.map +1 -1
- package/esm/socket/index.d.ts +2 -2
- package/esm/socket/index.js +2 -2
- package/esm/socket/socket.d.ts +59 -59
- package/esm/socket/socket.d.ts.map +1 -1
- package/esm/socket/socket.js +118 -118
- package/esm/socket/socket.js.map +1 -1
- package/esm/utils/auto-reset-event.d.ts +9 -9
- package/esm/utils/auto-reset-event.d.ts.map +1 -1
- package/esm/utils/auto-reset-event.js +33 -33
- package/esm/utils/auto-reset-event.js.map +1 -1
- package/esm/utils/base64.d.ts +27 -27
- package/esm/utils/base64.js +246 -246
- package/esm/utils/conditional-variable.d.ts +9 -0
- package/esm/utils/conditional-variable.d.ts.map +1 -0
- package/esm/utils/conditional-variable.js +34 -0
- package/esm/utils/conditional-variable.js.map +1 -0
- package/esm/utils/index.d.ts +4 -3
- package/esm/utils/index.d.ts.map +1 -1
- package/esm/utils/index.js +4 -3
- package/esm/utils/index.js.map +1 -1
- package/package.json +11 -10
- package/src/adb.ts +47 -37
- package/src/auth.ts +7 -6
- package/src/backend.ts +4 -4
- package/src/commands/base.ts +1 -1
- package/src/commands/framebuffer.ts +4 -4
- package/src/commands/index.ts +7 -8
- package/src/commands/reverse.ts +35 -10
- package/src/commands/subprocess/command.ts +12 -4
- package/src/commands/subprocess/index.ts +3 -3
- package/src/commands/subprocess/protocols/index.ts +3 -3
- package/src/commands/subprocess/protocols/none.ts +25 -11
- package/src/commands/subprocess/protocols/shell.ts +50 -28
- package/src/commands/subprocess/protocols/types.ts +8 -7
- package/src/commands/subprocess/utils.ts +1 -1
- package/src/commands/sync/index.ts +8 -7
- package/src/commands/sync/list.ts +42 -23
- package/src/commands/sync/pull.ts +40 -45
- package/src/commands/sync/push.ts +146 -39
- package/src/commands/sync/request.ts +20 -15
- package/src/commands/sync/response.ts +7 -6
- package/src/commands/sync/socket.ts +97 -0
- package/src/commands/sync/stat.ts +47 -42
- package/src/commands/sync/sync.ts +68 -108
- package/src/commands/tcpip.ts +5 -5
- package/src/features.ts +9 -6
- package/src/packet.ts +19 -34
- package/src/socket/dispatcher.ts +32 -47
- package/src/socket/index.ts +2 -2
- package/src/socket/socket.ts +26 -17
- package/src/utils/auto-reset-event.ts +14 -15
- package/src/utils/conditional-variable.ts +45 -0
- package/src/utils/index.ts +4 -3
- package/tsconfig.build.tsbuildinfo +1 -1
- package/src/commands/install.ts +0 -40
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type {
|
|
2
|
+
Consumable,
|
|
3
|
+
ReadableStream,
|
|
4
|
+
WritableStream,
|
|
4
5
|
} from "@yume-chan/stream-extra";
|
|
5
|
-
import {
|
|
6
|
+
import type { ValueOrPromise } from "@yume-chan/struct";
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
8
|
+
import type { Adb } from "../../../adb.js";
|
|
9
|
+
import type { AdbSocket } from "../../../socket/index.js";
|
|
9
10
|
|
|
10
11
|
export interface AdbSubprocessProtocol {
|
|
11
12
|
/**
|
|
12
13
|
* A WritableStream that writes to the `stdin` stream.
|
|
13
14
|
*/
|
|
14
|
-
readonly stdin: WritableStream<Uint8Array
|
|
15
|
+
readonly stdin: WritableStream<Consumable<Uint8Array>>;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* The `stdout` stream of the process.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
1
|
+
export * from "./list.js";
|
|
2
|
+
export * from "./pull.js";
|
|
3
|
+
export * from "./push.js";
|
|
4
|
+
export * from "./request.js";
|
|
5
|
+
export * from "./response.js";
|
|
6
|
+
export * from "./socket.js";
|
|
7
|
+
export * from "./stat.js";
|
|
8
|
+
export * from "./sync.js";
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type BufferedReadableStream,
|
|
3
|
-
type WritableStreamDefaultWriter,
|
|
4
|
-
} from "@yume-chan/stream-extra";
|
|
5
1
|
import Struct from "@yume-chan/struct";
|
|
6
2
|
|
|
7
3
|
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
8
4
|
import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
type AdbSyncStat,
|
|
13
|
-
} from "./stat.js";
|
|
5
|
+
import type { AdbSyncSocket } from "./socket.js";
|
|
6
|
+
import type { AdbSyncStat } from "./stat.js";
|
|
7
|
+
import { AdbSyncLstatResponse, AdbSyncStatResponse } from "./stat.js";
|
|
14
8
|
|
|
15
9
|
export interface AdbSyncEntry extends AdbSyncStat {
|
|
16
10
|
name: string;
|
|
@@ -23,7 +17,7 @@ export const AdbSyncEntryResponse = new Struct({ littleEndian: true })
|
|
|
23
17
|
.extra({ id: AdbSyncResponseId.Entry as const });
|
|
24
18
|
|
|
25
19
|
export type AdbSyncEntryResponse =
|
|
26
|
-
typeof AdbSyncEntryResponse["TDeserializeResult"];
|
|
20
|
+
(typeof AdbSyncEntryResponse)["TDeserializeResult"];
|
|
27
21
|
|
|
28
22
|
export const AdbSyncEntry2Response = new Struct({ littleEndian: true })
|
|
29
23
|
.fields(AdbSyncStatResponse)
|
|
@@ -32,18 +26,17 @@ export const AdbSyncEntry2Response = new Struct({ littleEndian: true })
|
|
|
32
26
|
.extra({ id: AdbSyncResponseId.Entry2 as const });
|
|
33
27
|
|
|
34
28
|
export type AdbSyncEntry2Response =
|
|
35
|
-
typeof AdbSyncEntry2Response["TDeserializeResult"];
|
|
29
|
+
(typeof AdbSyncEntry2Response)["TDeserializeResult"];
|
|
36
30
|
|
|
37
|
-
export async function*
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
await adbSyncWriteRequest(writer, AdbSyncRequestId.List2, path);
|
|
31
|
+
export async function* adbSyncOpenDirV2(
|
|
32
|
+
socket: AdbSyncSocket,
|
|
33
|
+
path: string
|
|
34
|
+
): AsyncGenerator<AdbSyncEntry2Response, void, void> {
|
|
35
|
+
const locked = await socket.lock();
|
|
36
|
+
try {
|
|
37
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.ListV2, path);
|
|
45
38
|
for await (const item of adbSyncReadResponses(
|
|
46
|
-
|
|
39
|
+
locked,
|
|
47
40
|
AdbSyncResponseId.Entry2,
|
|
48
41
|
AdbSyncEntry2Response
|
|
49
42
|
)) {
|
|
@@ -55,13 +48,39 @@ export async function* adbSyncOpenDir(
|
|
|
55
48
|
}
|
|
56
49
|
yield item;
|
|
57
50
|
}
|
|
58
|
-
}
|
|
59
|
-
|
|
51
|
+
} finally {
|
|
52
|
+
locked.release();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export async function* adbSyncOpenDirV1(
|
|
57
|
+
socket: AdbSyncSocket,
|
|
58
|
+
path: string
|
|
59
|
+
): AsyncGenerator<AdbSyncEntryResponse, void, void> {
|
|
60
|
+
const locked = await socket.lock();
|
|
61
|
+
try {
|
|
62
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.List, path);
|
|
60
63
|
for await (const item of adbSyncReadResponses(
|
|
61
|
-
|
|
64
|
+
locked,
|
|
62
65
|
AdbSyncResponseId.Entry,
|
|
63
66
|
AdbSyncEntryResponse
|
|
64
67
|
)) {
|
|
68
|
+
yield item;
|
|
69
|
+
}
|
|
70
|
+
} finally {
|
|
71
|
+
locked.release();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export async function* adbSyncOpenDir(
|
|
76
|
+
socket: AdbSyncSocket,
|
|
77
|
+
path: string,
|
|
78
|
+
v2: boolean
|
|
79
|
+
): AsyncGenerator<AdbSyncEntry, void, void> {
|
|
80
|
+
if (v2) {
|
|
81
|
+
yield* adbSyncOpenDirV2(socket, path);
|
|
82
|
+
} else {
|
|
83
|
+
for await (const item of adbSyncOpenDirV1(socket, path)) {
|
|
65
84
|
// Convert to same format as `AdbSyncEntry2Response` for easier consumption.
|
|
66
85
|
// However it will add some overhead.
|
|
67
86
|
yield {
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type BufferedReadableStream,
|
|
4
|
-
type WritableStreamDefaultWriter,
|
|
5
|
-
} from "@yume-chan/stream-extra";
|
|
1
|
+
import type { ReadableStream } from "@yume-chan/stream-extra";
|
|
2
|
+
import { PushReadableStream } from "@yume-chan/stream-extra";
|
|
6
3
|
import Struct from "@yume-chan/struct";
|
|
7
4
|
|
|
8
5
|
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
9
6
|
import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
|
|
7
|
+
import type { AdbSyncSocket } from "./socket.js";
|
|
10
8
|
|
|
11
9
|
export const AdbSyncDataResponse = new Struct({ littleEndian: true })
|
|
12
10
|
.uint32("dataLength")
|
|
@@ -14,49 +12,46 @@ export const AdbSyncDataResponse = new Struct({ littleEndian: true })
|
|
|
14
12
|
.extra({ id: AdbSyncResponseId.Data as const });
|
|
15
13
|
|
|
16
14
|
export type AdbSyncDataResponse =
|
|
17
|
-
typeof AdbSyncDataResponse["TDeserializeResult"];
|
|
15
|
+
(typeof AdbSyncDataResponse)["TDeserializeResult"];
|
|
16
|
+
|
|
17
|
+
export async function* adbSyncPullGenerator(
|
|
18
|
+
socket: AdbSyncSocket,
|
|
19
|
+
path: string
|
|
20
|
+
): AsyncGenerator<Uint8Array, void, void> {
|
|
21
|
+
const locked = await socket.lock();
|
|
22
|
+
let done = false;
|
|
23
|
+
try {
|
|
24
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.Receive, path);
|
|
25
|
+
for await (const packet of adbSyncReadResponses(
|
|
26
|
+
locked,
|
|
27
|
+
AdbSyncResponseId.Data,
|
|
28
|
+
AdbSyncDataResponse
|
|
29
|
+
)) {
|
|
30
|
+
yield packet.data;
|
|
31
|
+
}
|
|
32
|
+
done = true;
|
|
33
|
+
} finally {
|
|
34
|
+
if (!done) {
|
|
35
|
+
// sync pull can't be cancelled, so we have to read all data
|
|
36
|
+
for await (const packet of adbSyncReadResponses(
|
|
37
|
+
locked,
|
|
38
|
+
AdbSyncResponseId.Data,
|
|
39
|
+
AdbSyncDataResponse
|
|
40
|
+
)) {
|
|
41
|
+
void packet;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
locked.release();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
18
47
|
|
|
19
48
|
export function adbSyncPull(
|
|
20
|
-
|
|
21
|
-
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
49
|
+
socket: AdbSyncSocket,
|
|
22
50
|
path: string
|
|
23
51
|
): ReadableStream<Uint8Array> {
|
|
24
|
-
|
|
25
|
-
|
|
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) {
|
|
43
|
-
controller.close();
|
|
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
|
-
},
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
highWaterMark: 16 * 1024,
|
|
57
|
-
size(chunk) {
|
|
58
|
-
return chunk.byteLength;
|
|
59
|
-
},
|
|
52
|
+
return new PushReadableStream(async (controller) => {
|
|
53
|
+
for await (const data of adbSyncPullGenerator(socket, path)) {
|
|
54
|
+
await controller.enqueue(data);
|
|
60
55
|
}
|
|
61
|
-
);
|
|
56
|
+
});
|
|
62
57
|
}
|
|
@@ -1,52 +1,159 @@
|
|
|
1
|
+
import type { Consumable, ReadableStream } from "@yume-chan/stream-extra";
|
|
1
2
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type BufferedReadableStream,
|
|
6
|
-
type WritableStreamDefaultWriter,
|
|
3
|
+
AbortController,
|
|
4
|
+
ConsumableWritableStream,
|
|
5
|
+
DistributionStream,
|
|
7
6
|
} from "@yume-chan/stream-extra";
|
|
8
|
-
import Struct from "@yume-chan/struct";
|
|
7
|
+
import Struct, { placeholder } from "@yume-chan/struct";
|
|
9
8
|
|
|
10
9
|
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
|
11
10
|
import { AdbSyncResponseId, adbSyncReadResponse } from "./response.js";
|
|
11
|
+
import type { AdbSyncSocket, AdbSyncSocketLocked } from "./socket.js";
|
|
12
12
|
import { LinuxFileType } from "./stat.js";
|
|
13
13
|
|
|
14
|
+
const NOOP = () => {
|
|
15
|
+
// no-op
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const ADB_SYNC_MAX_PACKET_SIZE = 64 * 1024;
|
|
19
|
+
|
|
20
|
+
export interface AdbSyncPushV1Options {
|
|
21
|
+
socket: AdbSyncSocket;
|
|
22
|
+
filename: string;
|
|
23
|
+
file: ReadableStream<Consumable<Uint8Array>>;
|
|
24
|
+
mode?: number;
|
|
25
|
+
mtime?: number;
|
|
26
|
+
packetSize?: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
14
29
|
export const AdbSyncOkResponse = new Struct({ littleEndian: true }).uint32(
|
|
15
30
|
"unused"
|
|
16
31
|
);
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
async function pipeFile(
|
|
34
|
+
locked: AdbSyncSocketLocked,
|
|
35
|
+
file: ReadableStream<Consumable<Uint8Array>>,
|
|
36
|
+
packetSize: number,
|
|
37
|
+
mtime: number
|
|
38
|
+
) {
|
|
39
|
+
// Read and write in parallel,
|
|
40
|
+
// allow error response to abort the write.
|
|
41
|
+
const abortController = new AbortController();
|
|
42
|
+
file.pipeThrough(new DistributionStream(packetSize, true))
|
|
43
|
+
.pipeTo(
|
|
44
|
+
new ConsumableWritableStream({
|
|
45
|
+
write: async (chunk) => {
|
|
46
|
+
await adbSyncWriteRequest(
|
|
47
|
+
locked,
|
|
48
|
+
AdbSyncRequestId.Data,
|
|
49
|
+
chunk
|
|
50
|
+
);
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
{ signal: abortController.signal }
|
|
54
|
+
)
|
|
55
|
+
.then(async () => {
|
|
56
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.Done, mtime);
|
|
57
|
+
await locked.flush();
|
|
58
|
+
}, NOOP);
|
|
59
|
+
|
|
60
|
+
await adbSyncReadResponse(
|
|
61
|
+
locked,
|
|
62
|
+
AdbSyncResponseId.Ok,
|
|
63
|
+
AdbSyncOkResponse
|
|
64
|
+
).catch((e) => {
|
|
65
|
+
abortController.abort();
|
|
66
|
+
throw e;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export async function adbSyncPushV1({
|
|
71
|
+
socket,
|
|
72
|
+
filename,
|
|
73
|
+
file,
|
|
74
|
+
mode = (LinuxFileType.File << 12) | 0o666,
|
|
75
|
+
mtime = (Date.now() / 1000) | 0,
|
|
76
|
+
packetSize = ADB_SYNC_MAX_PACKET_SIZE,
|
|
77
|
+
}: AdbSyncPushV1Options) {
|
|
78
|
+
const locked = await socket.lock();
|
|
79
|
+
try {
|
|
80
|
+
const pathAndMode = `${filename},${mode.toString()}`;
|
|
81
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.Send, pathAndMode);
|
|
82
|
+
await pipeFile(locked, file, packetSize, mtime);
|
|
83
|
+
} finally {
|
|
84
|
+
locked.release();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export enum AdbSyncSendV2Flags {
|
|
89
|
+
None = 0,
|
|
90
|
+
Brotli = 1,
|
|
91
|
+
/**
|
|
92
|
+
* 2
|
|
93
|
+
*/
|
|
94
|
+
Lz4 = 1 << 1,
|
|
95
|
+
/**
|
|
96
|
+
* 4
|
|
97
|
+
*/
|
|
98
|
+
Zstd = 1 << 2,
|
|
99
|
+
/**
|
|
100
|
+
* 0x80000000
|
|
101
|
+
*/
|
|
102
|
+
DryRun = (1 << 31) >>> 0,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface AdbSyncPushV2Options extends AdbSyncPushV1Options {
|
|
106
|
+
dryRun?: boolean;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const AdbSyncSendV2Request = new Struct({ littleEndian: true })
|
|
110
|
+
.uint32("id", placeholder<AdbSyncRequestId>())
|
|
111
|
+
.uint32("mode")
|
|
112
|
+
.uint32("flags", placeholder<AdbSyncSendV2Flags>());
|
|
113
|
+
|
|
114
|
+
export async function adbSyncPushV2({
|
|
115
|
+
socket,
|
|
116
|
+
filename,
|
|
117
|
+
file,
|
|
118
|
+
mode = (LinuxFileType.File << 12) | 0o666,
|
|
119
|
+
mtime = (Date.now() / 1000) | 0,
|
|
120
|
+
packetSize = ADB_SYNC_MAX_PACKET_SIZE,
|
|
121
|
+
dryRun = false,
|
|
122
|
+
}: AdbSyncPushV2Options) {
|
|
123
|
+
const locked = await socket.lock();
|
|
124
|
+
try {
|
|
125
|
+
await adbSyncWriteRequest(locked, AdbSyncRequestId.SendV2, filename);
|
|
126
|
+
|
|
127
|
+
let flags: AdbSyncSendV2Flags = AdbSyncSendV2Flags.None;
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
flags |= AdbSyncSendV2Flags.DryRun;
|
|
130
|
+
}
|
|
131
|
+
await locked.write(
|
|
132
|
+
AdbSyncSendV2Request.serialize({
|
|
133
|
+
id: AdbSyncRequestId.SendV2,
|
|
134
|
+
mode,
|
|
135
|
+
flags,
|
|
136
|
+
})
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
await pipeFile(locked, file, packetSize, mtime);
|
|
140
|
+
} finally {
|
|
141
|
+
locked.release();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface AdbSyncPushOptions extends AdbSyncPushV2Options {
|
|
146
|
+
v2: boolean;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export function adbSyncPush(options: AdbSyncPushOptions) {
|
|
150
|
+
if (options.v2) {
|
|
151
|
+
return adbSyncPushV2(options);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (options.dryRun) {
|
|
155
|
+
throw new Error("dryRun is not supported in v1");
|
|
156
|
+
}
|
|
19
157
|
|
|
20
|
-
|
|
21
|
-
stream: BufferedReadableStream,
|
|
22
|
-
writer: WritableStreamDefaultWriter<Uint8Array>,
|
|
23
|
-
filename: string,
|
|
24
|
-
mode: number = (LinuxFileType.File << 12) | 0o666,
|
|
25
|
-
mtime: number = (Date.now() / 1000) | 0,
|
|
26
|
-
packetSize: number = ADB_SYNC_MAX_PACKET_SIZE
|
|
27
|
-
): WritableStream<Uint8Array> {
|
|
28
|
-
return pipeFrom(
|
|
29
|
-
new WritableStream<Uint8Array>({
|
|
30
|
-
async start() {
|
|
31
|
-
const pathAndMode = `${filename},${mode.toString()}`;
|
|
32
|
-
await adbSyncWriteRequest(
|
|
33
|
-
writer,
|
|
34
|
-
AdbSyncRequestId.Send,
|
|
35
|
-
pathAndMode
|
|
36
|
-
);
|
|
37
|
-
},
|
|
38
|
-
async write(chunk) {
|
|
39
|
-
await adbSyncWriteRequest(writer, AdbSyncRequestId.Data, chunk);
|
|
40
|
-
},
|
|
41
|
-
async close() {
|
|
42
|
-
await adbSyncWriteRequest(writer, AdbSyncRequestId.Done, mtime);
|
|
43
|
-
await adbSyncReadResponse(
|
|
44
|
-
stream,
|
|
45
|
-
AdbSyncResponseId.Ok,
|
|
46
|
-
AdbSyncOkResponse
|
|
47
|
-
);
|
|
48
|
-
},
|
|
49
|
-
}),
|
|
50
|
-
new ChunkStream(packetSize)
|
|
51
|
-
);
|
|
158
|
+
return adbSyncPushV1(options);
|
|
52
159
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { type WritableStreamDefaultWriter } from "@yume-chan/stream-extra";
|
|
2
1
|
import Struct from "@yume-chan/struct";
|
|
3
2
|
|
|
4
3
|
import { encodeUtf8 } from "../../utils/index.js";
|
|
5
4
|
|
|
6
5
|
export enum AdbSyncRequestId {
|
|
7
6
|
List = "LIST",
|
|
8
|
-
|
|
7
|
+
ListV2 = "LIS2",
|
|
9
8
|
Send = "SEND",
|
|
9
|
+
SendV2 = "SND2",
|
|
10
10
|
Lstat = "STAT",
|
|
11
11
|
Stat = "STA2",
|
|
12
|
-
|
|
12
|
+
LstatV2 = "LST2",
|
|
13
13
|
Data = "DATA",
|
|
14
14
|
Done = "DONE",
|
|
15
15
|
Receive = "RECV",
|
|
@@ -23,27 +23,32 @@ export const AdbSyncDataRequest = new Struct({ littleEndian: true })
|
|
|
23
23
|
.fields(AdbSyncNumberRequest)
|
|
24
24
|
.uint8Array("data", { lengthField: "arg" });
|
|
25
25
|
|
|
26
|
+
export interface AdbSyncWritable {
|
|
27
|
+
write(buffer: Uint8Array): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
export async function adbSyncWriteRequest(
|
|
27
|
-
|
|
31
|
+
writable: AdbSyncWritable,
|
|
28
32
|
id: AdbSyncRequestId | string,
|
|
29
33
|
value: number | string | Uint8Array
|
|
30
34
|
): Promise<void> {
|
|
31
|
-
let buffer: Uint8Array;
|
|
32
35
|
if (typeof value === "number") {
|
|
33
|
-
buffer = AdbSyncNumberRequest.serialize({
|
|
36
|
+
const buffer = AdbSyncNumberRequest.serialize({
|
|
34
37
|
id,
|
|
35
38
|
arg: value,
|
|
36
39
|
});
|
|
40
|
+
await writable.write(buffer);
|
|
37
41
|
} else if (typeof value === "string") {
|
|
38
|
-
buffer
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
// Let `writable` buffer writes
|
|
43
|
+
const buffer = encodeUtf8(value);
|
|
44
|
+
await writable.write(
|
|
45
|
+
AdbSyncNumberRequest.serialize({ id, arg: buffer.byteLength })
|
|
46
|
+
);
|
|
47
|
+
await writable.write(buffer);
|
|
42
48
|
} else {
|
|
43
|
-
|
|
44
|
-
id,
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
await writable.write(
|
|
50
|
+
AdbSyncNumberRequest.serialize({ id, arg: value.byteLength })
|
|
51
|
+
);
|
|
52
|
+
await writable.write(value);
|
|
47
53
|
}
|
|
48
|
-
await writer.write(buffer);
|
|
49
54
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type {
|
|
2
|
+
StructAsyncDeserializeStream,
|
|
3
|
+
StructLike,
|
|
4
|
+
StructValueType,
|
|
5
5
|
} from "@yume-chan/struct";
|
|
6
|
+
import Struct from "@yume-chan/struct";
|
|
6
7
|
|
|
7
8
|
import { decodeUtf8 } from "../../utils/index.js";
|
|
8
9
|
|
|
@@ -26,7 +27,7 @@ export const AdbSyncFailResponse = new Struct({ littleEndian: true })
|
|
|
26
27
|
});
|
|
27
28
|
|
|
28
29
|
export async function adbSyncReadResponse<T>(
|
|
29
|
-
stream:
|
|
30
|
+
stream: StructAsyncDeserializeStream,
|
|
30
31
|
id: AdbSyncResponseId,
|
|
31
32
|
type: StructLike<T>
|
|
32
33
|
): Promise<T> {
|
|
@@ -45,7 +46,7 @@ export async function adbSyncReadResponse<T>(
|
|
|
45
46
|
export async function* adbSyncReadResponses<
|
|
46
47
|
T extends Struct<object, PropertyKey, object, any>
|
|
47
48
|
>(
|
|
48
|
-
stream:
|
|
49
|
+
stream: StructAsyncDeserializeStream,
|
|
49
50
|
id: AdbSyncResponseId,
|
|
50
51
|
type: T
|
|
51
52
|
): AsyncGenerator<StructValueType<T>, void, void> {
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Consumable,
|
|
3
|
+
WritableStreamDefaultWriter,
|
|
4
|
+
} from "@yume-chan/stream-extra";
|
|
5
|
+
import {
|
|
6
|
+
BufferCombiner,
|
|
7
|
+
BufferedReadableStream,
|
|
8
|
+
ConsumableWritableStream,
|
|
9
|
+
} from "@yume-chan/stream-extra";
|
|
10
|
+
import type { StructAsyncDeserializeStream } from "@yume-chan/struct";
|
|
11
|
+
|
|
12
|
+
import type { AdbSocket } from "../../index.js";
|
|
13
|
+
import { AutoResetEvent } from "../../index.js";
|
|
14
|
+
|
|
15
|
+
export class AdbSyncSocketLocked implements StructAsyncDeserializeStream {
|
|
16
|
+
private readonly _writer: WritableStreamDefaultWriter<
|
|
17
|
+
Consumable<Uint8Array>
|
|
18
|
+
>;
|
|
19
|
+
private readonly _readable: BufferedReadableStream;
|
|
20
|
+
private readonly _socketLock: AutoResetEvent;
|
|
21
|
+
private readonly _writeLock = new AutoResetEvent();
|
|
22
|
+
private readonly _combiner: BufferCombiner;
|
|
23
|
+
|
|
24
|
+
public constructor(
|
|
25
|
+
writer: WritableStreamDefaultWriter<Consumable<Uint8Array>>,
|
|
26
|
+
readable: BufferedReadableStream,
|
|
27
|
+
bufferSize: number,
|
|
28
|
+
lock: AutoResetEvent
|
|
29
|
+
) {
|
|
30
|
+
this._writer = writer;
|
|
31
|
+
this._readable = readable;
|
|
32
|
+
this._socketLock = lock;
|
|
33
|
+
this._combiner = new BufferCombiner(bufferSize);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private async writeInnerStream(buffer: Uint8Array) {
|
|
37
|
+
await ConsumableWritableStream.write(this._writer, buffer);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async flush() {
|
|
41
|
+
try {
|
|
42
|
+
await this._writeLock.wait();
|
|
43
|
+
const buffer = this._combiner.flush();
|
|
44
|
+
if (buffer) {
|
|
45
|
+
await this.writeInnerStream(buffer);
|
|
46
|
+
}
|
|
47
|
+
} finally {
|
|
48
|
+
this._writeLock.notifyOne();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async write(data: Uint8Array) {
|
|
53
|
+
try {
|
|
54
|
+
await this._writeLock.wait();
|
|
55
|
+
for (const buffer of this._combiner.push(data)) {
|
|
56
|
+
await this.writeInnerStream(buffer);
|
|
57
|
+
}
|
|
58
|
+
} finally {
|
|
59
|
+
this._writeLock.notifyOne();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public async read(length: number) {
|
|
64
|
+
await this.flush();
|
|
65
|
+
return await this._readable.read(length);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public release(): void {
|
|
69
|
+
this._combiner.flush();
|
|
70
|
+
this._socketLock.notifyOne();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class AdbSyncSocket {
|
|
75
|
+
private _lock = new AutoResetEvent();
|
|
76
|
+
private _socket: AdbSocket;
|
|
77
|
+
private _locked: AdbSyncSocketLocked;
|
|
78
|
+
|
|
79
|
+
public constructor(socket: AdbSocket, bufferSize: number) {
|
|
80
|
+
this._socket = socket;
|
|
81
|
+
this._locked = new AdbSyncSocketLocked(
|
|
82
|
+
socket.writable.getWriter(),
|
|
83
|
+
new BufferedReadableStream(socket.readable),
|
|
84
|
+
bufferSize,
|
|
85
|
+
this._lock
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public async lock() {
|
|
90
|
+
await this._lock.wait();
|
|
91
|
+
return this._locked;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public async close() {
|
|
95
|
+
await this._socket.close();
|
|
96
|
+
}
|
|
97
|
+
}
|