mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-05 19:42:15 +02:00
refactor(struct): improve tree-shaking
This commit is contained in:
parent
e8d59b232e
commit
c91baa9116
32 changed files with 266 additions and 266 deletions
|
@ -1,12 +1,12 @@
|
|||
import { BufferedReadableStream } from "@yume-chan/stream-extra";
|
||||
import type { StructValue } from "@yume-chan/struct";
|
||||
import { buffer, Struct, StructEmptyError, u32 } from "@yume-chan/struct";
|
||||
import { buffer, struct, StructEmptyError, u32 } from "@yume-chan/struct";
|
||||
|
||||
import type { Adb } from "../adb.js";
|
||||
|
||||
const Version = new Struct({ version: u32 }, { littleEndian: true });
|
||||
const Version = struct({ version: u32 }, { littleEndian: true });
|
||||
|
||||
export const AdbFrameBufferV1 = new Struct(
|
||||
export const AdbFrameBufferV1 = struct(
|
||||
{
|
||||
bpp: u32,
|
||||
size: u32,
|
||||
|
@ -27,7 +27,7 @@ export const AdbFrameBufferV1 = new Struct(
|
|||
|
||||
export type AdbFrameBufferV1 = StructValue<typeof AdbFrameBufferV1>;
|
||||
|
||||
export const AdbFrameBufferV2 = new Struct(
|
||||
export const AdbFrameBufferV2 = struct(
|
||||
{
|
||||
bpp: u32,
|
||||
colorSpace: u32,
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
import { BufferedReadableStream } from "@yume-chan/stream-extra";
|
||||
import {
|
||||
ExactReadableEndedError,
|
||||
Struct,
|
||||
encodeUtf8,
|
||||
ExactReadableEndedError,
|
||||
string,
|
||||
struct,
|
||||
} from "@yume-chan/struct";
|
||||
|
||||
import type { Adb, AdbIncomingSocketHandler } from "../adb.js";
|
||||
|
@ -19,7 +19,7 @@ export interface AdbForwardListener {
|
|||
remoteName: string;
|
||||
}
|
||||
|
||||
const AdbReverseStringResponse = new Struct(
|
||||
const AdbReverseStringResponse = struct(
|
||||
{
|
||||
length: string(4),
|
||||
content: string({
|
||||
|
@ -38,7 +38,6 @@ const AdbReverseStringResponse = new Struct(
|
|||
export class AdbReverseError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, new.target.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -50,7 +49,9 @@ export class AdbReverseNotSupportedError extends AdbReverseError {
|
|||
}
|
||||
}
|
||||
|
||||
const AdbReverseErrorResponse = new Struct(AdbReverseStringResponse.fields, {
|
||||
const AdbReverseErrorResponse = struct(
|
||||
/* #__PURE__ */ (() => AdbReverseStringResponse.fields)(),
|
||||
{
|
||||
littleEndian: true,
|
||||
postDeserialize: (value) => {
|
||||
// https://issuetracker.google.com/issues/37066218
|
||||
|
@ -62,7 +63,8 @@ const AdbReverseErrorResponse = new Struct(AdbReverseStringResponse.fields, {
|
|||
throw new AdbReverseError(value.content);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Like `hexToNumber`, it's much faster than first converting `buffer` to a string
|
||||
function decimalToNumber(buffer: Uint8Array) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
WritableStream,
|
||||
} from "@yume-chan/stream-extra";
|
||||
import type { StructValue } from "@yume-chan/struct";
|
||||
import { Struct, buffer, u32, u8 } from "@yume-chan/struct";
|
||||
import { buffer, struct, u32, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type { Adb, AdbSocket } from "../../../adb.js";
|
||||
import { AdbFeature } from "../../../features.js";
|
||||
|
@ -32,7 +32,7 @@ export type AdbShellProtocolId =
|
|||
(typeof AdbShellProtocolId)[keyof typeof AdbShellProtocolId];
|
||||
|
||||
// This packet format is used in both directions.
|
||||
export const AdbShellProtocolPacket = new Struct(
|
||||
export const AdbShellProtocolPacket = struct(
|
||||
{
|
||||
id: u8.as<AdbShellProtocolId>(),
|
||||
data: buffer(u32),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { StructValue } from "@yume-chan/struct";
|
||||
import { Struct, string, u32 } from "@yume-chan/struct";
|
||||
import { string, struct, u32 } from "@yume-chan/struct";
|
||||
|
||||
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
||||
import { AdbSyncResponseId, adbSyncReadResponses } from "./response.js";
|
||||
|
@ -15,21 +15,21 @@ export interface AdbSyncEntry extends AdbSyncStat {
|
|||
name: string;
|
||||
}
|
||||
|
||||
export const AdbSyncEntryResponse = new Struct(
|
||||
{
|
||||
export const AdbSyncEntryResponse = struct(
|
||||
/* #__PURE__ */ (() => ({
|
||||
...AdbSyncLstatResponse.fields,
|
||||
name: string(u32),
|
||||
},
|
||||
}))(),
|
||||
{ littleEndian: true, extra: AdbSyncLstatResponse.extra },
|
||||
);
|
||||
|
||||
export type AdbSyncEntryResponse = StructValue<typeof AdbSyncEntryResponse>;
|
||||
|
||||
export const AdbSyncEntry2Response = new Struct(
|
||||
{
|
||||
export const AdbSyncEntry2Response = struct(
|
||||
/* #__PURE__ */ (() => ({
|
||||
...AdbSyncStatResponse.fields,
|
||||
name: string(u32),
|
||||
},
|
||||
}))(),
|
||||
{ littleEndian: true, extra: AdbSyncStatResponse.extra },
|
||||
);
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import type { ReadableStream } from "@yume-chan/stream-extra";
|
||||
import { PushReadableStream } from "@yume-chan/stream-extra";
|
||||
import type { StructValue } from "@yume-chan/struct";
|
||||
import { buffer, Struct, u32 } from "@yume-chan/struct";
|
||||
import { buffer, struct, u32 } from "@yume-chan/struct";
|
||||
|
||||
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
||||
import { adbSyncReadResponses, AdbSyncResponseId } from "./response.js";
|
||||
import type { AdbSyncSocket } from "./socket.js";
|
||||
|
||||
export const AdbSyncDataResponse = new Struct(
|
||||
export const AdbSyncDataResponse = struct(
|
||||
{ data: buffer(u32) },
|
||||
{ littleEndian: true },
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
DistributionStream,
|
||||
MaybeConsumable,
|
||||
} from "@yume-chan/stream-extra";
|
||||
import { Struct, u32 } from "@yume-chan/struct";
|
||||
import { struct, u32 } from "@yume-chan/struct";
|
||||
|
||||
import { NOOP } from "../../utils/index.js";
|
||||
|
||||
|
@ -25,7 +25,7 @@ export interface AdbSyncPushV1Options {
|
|||
packetSize?: number;
|
||||
}
|
||||
|
||||
export const AdbSyncOkResponse = new Struct(
|
||||
export const AdbSyncOkResponse = struct(
|
||||
{ unused: u32 },
|
||||
{ littleEndian: true },
|
||||
);
|
||||
|
@ -114,7 +114,7 @@ export interface AdbSyncPushV2Options extends AdbSyncPushV1Options {
|
|||
dryRun?: boolean;
|
||||
}
|
||||
|
||||
export const AdbSyncSendV2Request = new Struct(
|
||||
export const AdbSyncSendV2Request = struct(
|
||||
{ id: u32, mode: u32, flags: u32.as<AdbSyncSendV2Flags>() },
|
||||
{ littleEndian: true },
|
||||
);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { encodeUtf8, Struct, u32 } from "@yume-chan/struct";
|
||||
import { encodeUtf8, struct, u32 } from "@yume-chan/struct";
|
||||
|
||||
import { adbSyncEncodeId } from "./response.js";
|
||||
|
||||
|
@ -15,7 +15,7 @@ export const AdbSyncRequestId = {
|
|||
Receive: adbSyncEncodeId("RECV"),
|
||||
} as const;
|
||||
|
||||
export const AdbSyncNumberRequest = new Struct(
|
||||
export const AdbSyncNumberRequest = struct(
|
||||
{ id: u32, arg: u32 },
|
||||
{ littleEndian: true },
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getUint32LittleEndian } from "@yume-chan/no-data-view";
|
||||
import type { AsyncExactReadable, StructLike } from "@yume-chan/struct";
|
||||
import { Struct, decodeUtf8, string, u32 } from "@yume-chan/struct";
|
||||
import { decodeUtf8, string, struct, u32 } from "@yume-chan/struct";
|
||||
|
||||
function encodeAsciiUnchecked(value: string): Uint8Array {
|
||||
const result = new Uint8Array(value.length);
|
||||
|
@ -36,7 +36,7 @@ export const AdbSyncResponseId = {
|
|||
|
||||
export class AdbSyncError extends Error {}
|
||||
|
||||
export const AdbSyncFailResponse = new Struct(
|
||||
export const AdbSyncFailResponse = struct(
|
||||
{ message: string(u32) },
|
||||
{
|
||||
littleEndian: true,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { StructValue } from "@yume-chan/struct";
|
||||
import { Struct, u32, u64 } from "@yume-chan/struct";
|
||||
import { struct, u32, u64 } from "@yume-chan/struct";
|
||||
|
||||
import { AdbSyncRequestId, adbSyncWriteRequest } from "./request.js";
|
||||
import { AdbSyncResponseId, adbSyncReadResponse } from "./response.js";
|
||||
|
@ -27,7 +27,7 @@ export interface AdbSyncStat {
|
|||
ctime?: bigint;
|
||||
}
|
||||
|
||||
export const AdbSyncLstatResponse = new Struct(
|
||||
export const AdbSyncLstatResponse = struct(
|
||||
{ mode: u32, size: u32, mtime: u32 },
|
||||
{
|
||||
littleEndian: true,
|
||||
|
@ -86,7 +86,7 @@ const AdbSyncStatErrorName =
|
|||
]),
|
||||
);
|
||||
|
||||
export const AdbSyncStatResponse = new Struct(
|
||||
export const AdbSyncStatResponse = struct(
|
||||
{
|
||||
error: u32.as<AdbSyncStatErrorCode>(),
|
||||
dev: u64,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Consumable, TransformStream } from "@yume-chan/stream-extra";
|
||||
import type { StructInit, StructValue } from "@yume-chan/struct";
|
||||
import { buffer, s32, Struct, u32 } from "@yume-chan/struct";
|
||||
import { buffer, s32, struct, u32 } from "@yume-chan/struct";
|
||||
|
||||
export const AdbCommand = {
|
||||
Auth: 0x48545541, // 'AUTH'
|
||||
|
@ -13,7 +13,7 @@ export const AdbCommand = {
|
|||
|
||||
export type AdbCommand = (typeof AdbCommand)[keyof typeof AdbCommand];
|
||||
|
||||
export const AdbPacketHeader = new Struct(
|
||||
export const AdbPacketHeader = struct(
|
||||
{
|
||||
command: u32,
|
||||
arg0: u32,
|
||||
|
@ -29,8 +29,11 @@ export type AdbPacketHeader = StructValue<typeof AdbPacketHeader>;
|
|||
|
||||
type AdbPacketHeaderInit = StructInit<typeof AdbPacketHeader>;
|
||||
|
||||
export const AdbPacket = new Struct(
|
||||
{ ...AdbPacketHeader.fields, payload: buffer("payloadLength") },
|
||||
export const AdbPacket = struct(
|
||||
/* #__PURE__ */ (() => ({
|
||||
...AdbPacketHeader.fields,
|
||||
payload: buffer("payloadLength"),
|
||||
}))(),
|
||||
{ littleEndian: true },
|
||||
);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
WritableStream,
|
||||
} from "@yume-chan/stream-extra";
|
||||
import type { AsyncExactReadable, StructValue } from "@yume-chan/struct";
|
||||
import { Struct, decodeUtf8, u16, u32 } from "@yume-chan/struct";
|
||||
import { decodeUtf8, struct, u16, u32 } from "@yume-chan/struct";
|
||||
|
||||
// `adb logcat` is an alias to `adb shell logcat`
|
||||
// so instead of adding to core library, it's implemented here
|
||||
|
@ -99,7 +99,7 @@ export interface LogcatOptions {
|
|||
const NANOSECONDS_PER_SECOND = /* #__PURE__ */ BigInt(1e9);
|
||||
|
||||
// https://cs.android.com/android/platform/superproject/+/master:system/logging/liblog/include/log/log_read.h;l=39;drc=82b5738732161dbaafb2e2f25cce19cd26b9157d
|
||||
export const LoggerEntry = new Struct(
|
||||
export const LoggerEntry = struct(
|
||||
{
|
||||
payloadSize: u16,
|
||||
headerSize: u16,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { Struct, u8 } from "@yume-chan/struct";
|
||||
import { struct, u8 } from "@yume-chan/struct";
|
||||
|
||||
export const EmptyControlMessage = new Struct(
|
||||
export const EmptyControlMessage = struct(
|
||||
{ type: u8 },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { Struct, u32, u8 } from "@yume-chan/struct";
|
||||
import { struct, u32, u8 } from "@yume-chan/struct";
|
||||
|
||||
export enum AndroidKeyEventAction {
|
||||
Down = 0,
|
||||
|
@ -206,7 +206,7 @@ export enum AndroidKeyCode {
|
|||
AndroidPaste,
|
||||
}
|
||||
|
||||
export const ScrcpyInjectKeyCodeControlMessage = new Struct(
|
||||
export const ScrcpyInjectKeyCodeControlMessage = struct(
|
||||
{
|
||||
type: u8,
|
||||
action: u8.as<AndroidKeyEventAction>(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { string, Struct, u32, u8 } from "@yume-chan/struct";
|
||||
import { string, struct, u32, u8 } from "@yume-chan/struct";
|
||||
|
||||
export const ScrcpyInjectTextControlMessage = new Struct(
|
||||
export const ScrcpyInjectTextControlMessage = struct(
|
||||
{ type: u8, text: string(u32) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { Struct, u8 } from "@yume-chan/struct";
|
||||
import { struct, u8 } from "@yume-chan/struct";
|
||||
|
||||
// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/SurfaceControl.java;l=659;drc=20303e05bf73796124ab70a279cf849b61b97905
|
||||
export const AndroidScreenPowerMode = {
|
||||
|
@ -10,7 +10,7 @@ export const AndroidScreenPowerMode = {
|
|||
export type AndroidScreenPowerMode =
|
||||
(typeof AndroidScreenPowerMode)[keyof typeof AndroidScreenPowerMode];
|
||||
|
||||
export const ScrcpySetScreenPowerModeControlMessage = new Struct(
|
||||
export const ScrcpySetScreenPowerModeControlMessage = struct(
|
||||
{ type: u8, mode: u8.as<AndroidScreenPowerMode>() },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import type { CodecOptions } from "./codec-options.js";
|
||||
|
||||
export enum ScrcpyLogLevel1_16 {
|
||||
Debug = "debug",
|
||||
Info = "info",
|
||||
Warn = "warn",
|
||||
Error = "error",
|
||||
}
|
||||
export type ScrcpyLogLevel1_16 = "debug" | "info" | "warn" | "error";
|
||||
|
||||
export enum ScrcpyVideoOrientation1_16 {
|
||||
Unlocked = -1,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { Struct, buffer, string, u16, u32, u64, u8 } from "@yume-chan/struct";
|
||||
import { buffer, string, struct, u16, u32, u64, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type { AndroidMotionEventAction } from "../../control/index.js";
|
||||
import {
|
||||
|
@ -24,14 +24,14 @@ export const SCRCPY_CONTROL_MESSAGE_TYPES_1_16: readonly ScrcpyControlMessageTyp
|
|||
/* 10 */ ScrcpyControlMessageType.RotateDevice,
|
||||
];
|
||||
|
||||
export const ScrcpyMediaStreamRawPacket = new Struct(
|
||||
export const ScrcpyMediaStreamRawPacket = struct(
|
||||
{ pts: u64, data: buffer(u32) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
||||
export const SCRCPY_MEDIA_PACKET_FLAG_CONFIG = 1n << 63n;
|
||||
|
||||
export const ScrcpyInjectTouchControlMessage1_16 = new Struct(
|
||||
export const ScrcpyInjectTouchControlMessage1_16 = struct(
|
||||
{
|
||||
type: u8,
|
||||
action: u8.as<AndroidMotionEventAction>(),
|
||||
|
@ -52,7 +52,7 @@ export type ScrcpyInjectTouchControlMessage1_16 = StructInit<
|
|||
|
||||
export const ScrcpyBackOrScreenOnControlMessage1_16 = EmptyControlMessage;
|
||||
|
||||
export const ScrcpySetClipboardControlMessage1_15 = new Struct(
|
||||
export const ScrcpySetClipboardControlMessage1_15 = struct(
|
||||
{ type: u8, content: string(u32) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
@ -61,7 +61,7 @@ export type ScrcpySetClipboardControlMessage1_15 = StructInit<
|
|||
typeof ScrcpySetClipboardControlMessage1_15
|
||||
>;
|
||||
|
||||
export const ScrcpyClipboardDeviceMessage = new Struct(
|
||||
export const ScrcpyClipboardDeviceMessage = struct(
|
||||
{ content: string(u32) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
|
|
@ -37,7 +37,7 @@ import {
|
|||
|
||||
import { CodecOptions } from "./codec-options.js";
|
||||
import type { ScrcpyOptionsInit1_16 } from "./init.js";
|
||||
import { ScrcpyLogLevel1_16, ScrcpyVideoOrientation1_16 } from "./init.js";
|
||||
import { ScrcpyVideoOrientation1_16 } from "./init.js";
|
||||
import {
|
||||
SCRCPY_CONTROL_MESSAGE_TYPES_1_16,
|
||||
SCRCPY_MEDIA_PACKET_FLAG_CONFIG,
|
||||
|
@ -52,7 +52,7 @@ import { ScrcpyScrollController1_16 } from "./scroll.js";
|
|||
|
||||
export class ScrcpyOptions1_16 extends ScrcpyOptions<ScrcpyOptionsInit1_16> {
|
||||
static readonly DEFAULTS = {
|
||||
logLevel: ScrcpyLogLevel1_16.Debug,
|
||||
logLevel: "debug",
|
||||
maxSize: 0,
|
||||
bitRate: 8_000_000,
|
||||
maxFps: 0,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { s32, Struct, u16, u32, u8 } from "@yume-chan/struct";
|
||||
import { s32, struct, u16, u32, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type { ScrcpyInjectScrollControlMessage } from "../../control/index.js";
|
||||
import { ScrcpyControlMessageType } from "../../control/index.js";
|
||||
|
@ -9,7 +9,7 @@ export interface ScrcpyScrollController {
|
|||
): Uint8Array | undefined;
|
||||
}
|
||||
|
||||
export const ScrcpyInjectScrollControlMessage1_16 = new Struct(
|
||||
export const ScrcpyInjectScrollControlMessage1_16 = struct(
|
||||
{
|
||||
type: u8.as(ScrcpyControlMessageType.InjectScroll as const),
|
||||
pointerX: u32,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { Struct, u8 } from "@yume-chan/struct";
|
||||
import { struct, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type {
|
||||
AndroidKeyEventAction,
|
||||
|
@ -17,22 +17,24 @@ import { ScrcpyOptions1_17 } from "./1_17.js";
|
|||
import type { ScrcpyEncoder } from "./types.js";
|
||||
import { ScrcpyOptions } from "./types.js";
|
||||
|
||||
export enum ScrcpyLogLevel1_18 {
|
||||
Verbose = "verbose",
|
||||
Debug = "debug",
|
||||
Info = "info",
|
||||
Warn = "warn",
|
||||
Error = "error",
|
||||
}
|
||||
export type ScrcpyLogLevel1_18 =
|
||||
| "verbose"
|
||||
| "debug"
|
||||
| "info"
|
||||
| "warn"
|
||||
| "error";
|
||||
|
||||
export enum ScrcpyVideoOrientation1_18 {
|
||||
Initial = -2,
|
||||
Unlocked = -1,
|
||||
Portrait = 0,
|
||||
Landscape = 1,
|
||||
PortraitFlipped = 2,
|
||||
LandscapeFlipped = 3,
|
||||
}
|
||||
export const ScrcpyVideoOrientation1_18 = {
|
||||
Initial: -2,
|
||||
Unlocked: -1,
|
||||
Portrait: 0,
|
||||
Landscape: 1,
|
||||
PortraitFlipped: 2,
|
||||
LandscapeFlipped: 3,
|
||||
};
|
||||
|
||||
export type ScrcpyVideoOrientation1_18 =
|
||||
(typeof ScrcpyVideoOrientation1_18)[keyof typeof ScrcpyVideoOrientation1_18];
|
||||
|
||||
export interface ScrcpyOptionsInit1_18
|
||||
extends Omit<ScrcpyOptionsInit1_17, "logLevel" | "lockVideoOrientation"> {
|
||||
|
@ -43,11 +45,11 @@ export interface ScrcpyOptionsInit1_18
|
|||
powerOffOnClose?: boolean;
|
||||
}
|
||||
|
||||
export const ScrcpyBackOrScreenOnControlMessage1_18 = new Struct(
|
||||
{
|
||||
export const ScrcpyBackOrScreenOnControlMessage1_18 = struct(
|
||||
/* #__PURE__ */ (() => ({
|
||||
...ScrcpyBackOrScreenOnControlMessage1_16.fields,
|
||||
action: u8.as<AndroidKeyEventAction>(),
|
||||
},
|
||||
}))(),
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
||||
|
@ -55,18 +57,16 @@ export type ScrcpyBackOrScreenOnControlMessage1_18 = StructInit<
|
|||
typeof ScrcpyBackOrScreenOnControlMessage1_18
|
||||
>;
|
||||
|
||||
export const SCRCPY_CONTROL_MESSAGE_TYPES_1_18 =
|
||||
SCRCPY_CONTROL_MESSAGE_TYPES_1_16.slice();
|
||||
SCRCPY_CONTROL_MESSAGE_TYPES_1_18.splice(
|
||||
6,
|
||||
0,
|
||||
ScrcpyControlMessageType.ExpandSettingPanel,
|
||||
);
|
||||
export const SCRCPY_CONTROL_MESSAGE_TYPES_1_18 = /* #__PURE__ */ (() => {
|
||||
const result = SCRCPY_CONTROL_MESSAGE_TYPES_1_16.slice();
|
||||
result.splice(6, 0, ScrcpyControlMessageType.ExpandSettingPanel);
|
||||
return result;
|
||||
})();
|
||||
|
||||
export class ScrcpyOptions1_18 extends ScrcpyOptions<ScrcpyOptionsInit1_18> {
|
||||
static readonly DEFAULTS = {
|
||||
...ScrcpyOptions1_17.DEFAULTS,
|
||||
logLevel: ScrcpyLogLevel1_18.Debug,
|
||||
logLevel: "debug",
|
||||
lockVideoOrientation: ScrcpyVideoOrientation1_18.Unlocked,
|
||||
powerOffOnClose: false,
|
||||
} as const satisfies Required<ScrcpyOptionsInit1_18>;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { PromiseResolver } from "@yume-chan/async";
|
||||
import type { AsyncExactReadable, StructInit } from "@yume-chan/struct";
|
||||
import { Struct, string, u32, u64, u8 } from "@yume-chan/struct";
|
||||
import { string, struct, u32, u64, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type { ScrcpySetClipboardControlMessage } from "../control/index.js";
|
||||
|
||||
|
@ -11,7 +11,7 @@ import type { ScrcpyOptionsInit1_18 } from "./1_18.js";
|
|||
import { ScrcpyOptions1_18 } from "./1_18.js";
|
||||
import { ScrcpyOptions, toScrcpyOptionValue } from "./types.js";
|
||||
|
||||
export const ScrcpyAckClipboardDeviceMessage = new Struct(
|
||||
export const ScrcpyAckClipboardDeviceMessage = struct(
|
||||
{ sequence: u64 },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
@ -24,7 +24,7 @@ function toSnakeCase(input: string): string {
|
|||
return input.replace(/([A-Z])/g, "_$1").toLowerCase();
|
||||
}
|
||||
|
||||
export const ScrcpySetClipboardControlMessage1_21 = new Struct(
|
||||
export const ScrcpySetClipboardControlMessage1_21 = struct(
|
||||
{
|
||||
type: u8,
|
||||
sequence: u64,
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import type { StructInit } from "@yume-chan/struct";
|
||||
import { s32, Struct } from "@yume-chan/struct";
|
||||
import { s32, struct } from "@yume-chan/struct";
|
||||
|
||||
import {
|
||||
ScrcpyInjectScrollControlMessage1_16,
|
||||
ScrcpyScrollController1_16,
|
||||
} from "../1_16/index.js";
|
||||
|
||||
export const ScrcpyInjectScrollControlMessage1_22 = new Struct(
|
||||
{ ...ScrcpyInjectScrollControlMessage1_16.fields, buttons: s32 },
|
||||
export const ScrcpyInjectScrollControlMessage1_22 = struct(
|
||||
/* #__PURE__ */ (() => ({
|
||||
...ScrcpyInjectScrollControlMessage1_16.fields,
|
||||
buttons: s32,
|
||||
}))(),
|
||||
{ littleEndian: false },
|
||||
);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getInt16, setInt16 } from "@yume-chan/no-data-view";
|
||||
import type { Field, StructInit } from "@yume-chan/struct";
|
||||
import { bipedal, Struct, u16, u32, u8 } from "@yume-chan/struct";
|
||||
import { bipedal, struct, u16, u32, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type { ScrcpyInjectScrollControlMessage } from "../../control/index.js";
|
||||
import { ScrcpyControlMessageType } from "../../control/index.js";
|
||||
|
@ -23,7 +23,7 @@ export const ScrcpySignedFloat: Field<number, never, never> = {
|
|||
}),
|
||||
};
|
||||
|
||||
export const ScrcpyInjectScrollControlMessage1_25 = new Struct(
|
||||
export const ScrcpyInjectScrollControlMessage1_25 = struct(
|
||||
{
|
||||
type: u8.as(ScrcpyControlMessageType.InjectScroll as const),
|
||||
pointerX: u32,
|
||||
|
|
|
@ -5,7 +5,7 @@ import {
|
|||
PushReadableStream,
|
||||
} from "@yume-chan/stream-extra";
|
||||
import type { MaybePromiseLike, StructInit } from "@yume-chan/struct";
|
||||
import { Struct, u16, u32, u64, u8 } from "@yume-chan/struct";
|
||||
import { struct, u16, u32, u64, u8 } from "@yume-chan/struct";
|
||||
|
||||
import type {
|
||||
AndroidMotionEventAction,
|
||||
|
@ -30,7 +30,7 @@ import type {
|
|||
} from "./types.js";
|
||||
import { ScrcpyOptions } from "./types.js";
|
||||
|
||||
export const ScrcpyInjectTouchControlMessage2_0 = new Struct(
|
||||
export const ScrcpyInjectTouchControlMessage2_0 = struct(
|
||||
{
|
||||
type: u8,
|
||||
action: u8.as<AndroidMotionEventAction>(),
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { ScrcpyLogLevel1_18, ScrcpyVideoOrientation1_18 } from "./1_18.js";
|
||||
import type { ScrcpyLogLevel1_18 } from "./1_18.js";
|
||||
import { ScrcpyVideoOrientation1_18 } from "./1_18.js";
|
||||
import type { ScrcpyOptionsInit2_3 } from "./2_3.js";
|
||||
import { ScrcpyOptions2_3 } from "./2_3.js";
|
||||
|
||||
export const ScrcpyLogLevel = ScrcpyLogLevel1_18;
|
||||
export type ScrcpyLogLevel = ScrcpyLogLevel1_18;
|
||||
|
||||
export const ScrcpyVideoOrientation = ScrcpyVideoOrientation1_18;
|
||||
|
|
|
@ -25,9 +25,9 @@ $ npm i @yume-chan/struct
|
|||
## Quick Start
|
||||
|
||||
```ts
|
||||
import { Struct, u8, u16, s32, buffer, string } from "@yume-chan/struct";
|
||||
import { struct, u8, u16, s32, buffer, string } from "@yume-chan/struct";
|
||||
|
||||
const Message = new Struct(
|
||||
const Message = struct(
|
||||
{
|
||||
a: u8,
|
||||
b: u16,
|
||||
|
@ -94,7 +94,7 @@ const MyField: Field<number, never, never> = {
|
|||
},
|
||||
};
|
||||
|
||||
const Message2 = new Struct({
|
||||
const Message2 = struct({
|
||||
a: u8,
|
||||
b: MyField,
|
||||
});
|
||||
|
|
|
@ -4,15 +4,12 @@ import { describe, it } from "node:test";
|
|||
import { buffer } from "./buffer.js";
|
||||
import type { ExactReadable } from "./readable.js";
|
||||
import { ExactReadableEndedError } from "./readable.js";
|
||||
import { Struct } from "./struct.js";
|
||||
import { struct } from "./struct.js";
|
||||
|
||||
describe("buffer", () => {
|
||||
describe("fixed size", () => {
|
||||
it("should deserialize", () => {
|
||||
const A = new Struct(
|
||||
{ value: buffer(10) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
const A = struct({ value: buffer(10) }, { littleEndian: false });
|
||||
const reader: ExactReadable = {
|
||||
position: 0,
|
||||
readExactly() {
|
||||
|
@ -25,10 +22,7 @@ describe("buffer", () => {
|
|||
});
|
||||
|
||||
it("should throw for not enough data", () => {
|
||||
const A = new Struct(
|
||||
{ value: buffer(10) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
const A = struct({ value: buffer(10) }, { littleEndian: false });
|
||||
const reader: ExactReadable = {
|
||||
position: 0,
|
||||
readExactly() {
|
||||
|
@ -43,10 +37,7 @@ describe("buffer", () => {
|
|||
});
|
||||
|
||||
it("should throw for no data", () => {
|
||||
const A = new Struct(
|
||||
{ value: buffer(10) },
|
||||
{ littleEndian: false },
|
||||
);
|
||||
const A = struct({ value: buffer(10) }, { littleEndian: false });
|
||||
const reader: ExactReadable = {
|
||||
position: 0,
|
||||
readExactly() {
|
||||
|
|
|
@ -42,14 +42,16 @@ export interface BufferLike {
|
|||
|
||||
export const EmptyUint8Array = new Uint8Array(0);
|
||||
|
||||
export const buffer: BufferLike = ((
|
||||
// This is required for Rollup tree-shaking to work.
|
||||
/* #__NO_SIDE_EFFECTS__ */
|
||||
function _buffer(
|
||||
lengthOrField:
|
||||
| string
|
||||
| number
|
||||
| Field<number, never, unknown>
|
||||
| BufferLengthConverter<string, unknown>,
|
||||
converter?: Converter<Uint8Array, unknown>,
|
||||
): Field<unknown, string, Record<string, unknown>> => {
|
||||
): Field<unknown, string, Record<string, unknown>> {
|
||||
if (typeof lengthOrField === "number") {
|
||||
if (converter) {
|
||||
return {
|
||||
|
@ -226,4 +228,6 @@ export const buffer: BufferLike = ((
|
|||
return reader.readExactly(length);
|
||||
},
|
||||
};
|
||||
}) as never;
|
||||
}
|
||||
|
||||
export const buffer: BufferLike = _buffer as never;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import * as assert from "node:assert";
|
||||
import { describe, it } from "node:test";
|
||||
|
||||
import { Struct } from "./index.js";
|
||||
import { struct } from "./index.js";
|
||||
|
||||
describe("Struct", () => {
|
||||
describe("Index", () => {
|
||||
it("should export default Struct", () => {
|
||||
assert.ok(Struct);
|
||||
assert.ok(struct);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -25,15 +25,19 @@ export interface String {
|
|||
): Field<string, KOmitInit, KS>;
|
||||
}
|
||||
|
||||
export const string: String = ((
|
||||
// This is required for Rollup tree-shaking to work.
|
||||
/* #__NO_SIDE_EFFECTS__ */
|
||||
function _string(
|
||||
lengthOrField: string | number | BufferLengthConverter<string, unknown>,
|
||||
): Field<string, string, Record<string, unknown>> & {
|
||||
as: <T>(infer: T) => Field<T, string, Record<string, unknown>>;
|
||||
} => {
|
||||
} {
|
||||
const field = buffer(lengthOrField as never, {
|
||||
convert: decodeUtf8,
|
||||
back: encodeUtf8,
|
||||
});
|
||||
(field as never as { as: unknown }).as = () => field;
|
||||
return field as never;
|
||||
}) as never;
|
||||
}
|
||||
|
||||
export const string: String = _string as never;
|
||||
|
|
|
@ -2,11 +2,11 @@ import * as assert from "node:assert";
|
|||
import { describe, it } from "node:test";
|
||||
|
||||
import { u8 } from "./number.js";
|
||||
import { Struct } from "./struct.js";
|
||||
import { struct } from "./struct.js";
|
||||
|
||||
describe("Struct", () => {
|
||||
it("serialize", () => {
|
||||
const A = new Struct({ id: u8 }, { littleEndian: true });
|
||||
const A = struct({ id: u8 }, { littleEndian: true });
|
||||
assert.deepStrictEqual(A.serialize({ id: 10 }), new Uint8Array([10]));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -29,7 +29,7 @@ export type StructInit<
|
|||
export type StructValue<
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
T extends Struct<any, any, any>,
|
||||
> = ReturnType<Exclude<T["postDeserialize"], undefined>>;
|
||||
> = T extends Struct<any, any, infer P> ? P : never;
|
||||
|
||||
export class StructDeserializeError extends Error {
|
||||
constructor(message: string) {
|
||||
|
@ -55,26 +55,29 @@ export class StructEmptyError extends StructDeserializeError {
|
|||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type StructLike<T> = Struct<any, any, T>;
|
||||
|
||||
export class Struct<
|
||||
export interface Struct<
|
||||
T extends Record<string, Field<unknown, string, Partial<FieldsType<T>>>>,
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
Extra extends Record<PropertyKey, unknown> = {},
|
||||
Extra extends Record<PropertyKey, unknown> | undefined = undefined,
|
||||
PostDeserialize = FieldsType<T> & Extra,
|
||||
> {
|
||||
fields: T;
|
||||
size: number;
|
||||
|
||||
#fieldList: [string, Field<unknown, string, unknown>][] = [];
|
||||
|
||||
littleEndian: boolean;
|
||||
|
||||
extra: Extra;
|
||||
|
||||
postDeserialize?:
|
||||
| ((fields: FieldsType<T> & Extra) => PostDeserialize)
|
||||
| undefined;
|
||||
serialize(runtimeStruct: StructInit<this>): Uint8Array;
|
||||
serialize(runtimeStruct: StructInit<this>, buffer: Uint8Array): number;
|
||||
|
||||
constructor(
|
||||
deserialize(reader: ExactReadable): PostDeserialize;
|
||||
deserialize(reader: AsyncExactReadable): MaybePromiseLike<PostDeserialize>;
|
||||
}
|
||||
|
||||
/* #__NO_SIDE_EFFECTS__ */
|
||||
export function struct<
|
||||
T extends Record<string, Field<unknown, string, Partial<FieldsType<T>>>>,
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
Extra extends Record<PropertyKey, unknown> = {},
|
||||
PostDeserialize = FieldsType<T> & Extra,
|
||||
>(
|
||||
fields: T,
|
||||
options: {
|
||||
littleEndian?: boolean;
|
||||
|
@ -84,37 +87,36 @@ export class Struct<
|
|||
fields: FieldsType<T> & Extra,
|
||||
) => PostDeserialize;
|
||||
},
|
||||
) {
|
||||
this.#fieldList = Object.entries(fields);
|
||||
this.fields = fields;
|
||||
this.size = this.#fieldList.reduce(
|
||||
(sum, [, field]) => sum + field.size,
|
||||
0,
|
||||
);
|
||||
): Struct<T, Extra, PostDeserialize> {
|
||||
const fieldList = Object.entries(fields);
|
||||
const size = fieldList.reduce((sum, [, field]) => sum + field.size, 0);
|
||||
|
||||
this.littleEndian = !!options.littleEndian;
|
||||
this.extra = options.extra!;
|
||||
this.postDeserialize = options.postDeserialize;
|
||||
}
|
||||
const littleEndian = !!options.littleEndian;
|
||||
const extra = options.extra
|
||||
? Object.getOwnPropertyDescriptors(options.extra)
|
||||
: undefined;
|
||||
|
||||
serialize(runtimeStruct: StructInit<this>): Uint8Array;
|
||||
serialize(runtimeStruct: StructInit<this>, buffer: Uint8Array): number;
|
||||
return {
|
||||
fields,
|
||||
size,
|
||||
extra: options.extra,
|
||||
serialize(
|
||||
runtimeStruct: StructInit<this>,
|
||||
runtimeStruct: StructInit<Struct<T, Extra, PostDeserialize>>,
|
||||
buffer?: Uint8Array,
|
||||
): Uint8Array | number {
|
||||
for (const [key, field] of this.#fieldList) {
|
||||
for (const [key, field] of fieldList) {
|
||||
if (key in runtimeStruct) {
|
||||
field.preSerialize?.(
|
||||
runtimeStruct[key as never],
|
||||
runtimeStruct,
|
||||
runtimeStruct as never,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const sizes = this.#fieldList.map(
|
||||
const sizes = fieldList.map(
|
||||
([key, field]) =>
|
||||
field.dynamicSize?.(runtimeStruct[key as never]) ?? field.size,
|
||||
field.dynamicSize?.(runtimeStruct[key as never]) ??
|
||||
field.size,
|
||||
);
|
||||
const size = sizes.reduce((sum, size) => sum + size, 0);
|
||||
|
||||
|
@ -132,9 +134,9 @@ export class Struct<
|
|||
const context: SerializeContext = {
|
||||
buffer,
|
||||
index: 0,
|
||||
littleEndian: this.littleEndian,
|
||||
littleEndian,
|
||||
};
|
||||
for (const [index, [key, field]] of this.#fieldList.entries()) {
|
||||
for (const [index, [key, field]] of fieldList.entries()) {
|
||||
field.serialize(runtimeStruct[key as never], context);
|
||||
context.index += sizes[index]!;
|
||||
}
|
||||
|
@ -144,12 +146,8 @@ export class Struct<
|
|||
} else {
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
deserialize: {
|
||||
(reader: ExactReadable): PostDeserialize;
|
||||
(reader: AsyncExactReadable): MaybePromiseLike<PostDeserialize>;
|
||||
} = bipedal(function* (
|
||||
},
|
||||
deserialize: bipedal(function* (
|
||||
this: Struct<T, Extra, PostDeserialize>,
|
||||
then,
|
||||
reader: AsyncExactReadable,
|
||||
|
@ -157,15 +155,17 @@ export class Struct<
|
|||
const startPosition = reader.position;
|
||||
|
||||
const runtimeStruct = {} as Record<string, unknown>;
|
||||
const context: DeserializeContext<unknown> = {
|
||||
const context: DeserializeContext<Partial<FieldsType<T>>> = {
|
||||
reader,
|
||||
runtimeStruct,
|
||||
littleEndian: this.littleEndian,
|
||||
runtimeStruct: runtimeStruct as never,
|
||||
littleEndian: littleEndian,
|
||||
};
|
||||
|
||||
try {
|
||||
for (const [key, field] of this.#fieldList) {
|
||||
runtimeStruct[key] = yield* then(field.deserialize(context));
|
||||
for (const [key, field] of fieldList) {
|
||||
runtimeStruct[key] = yield* then(
|
||||
field.deserialize(context),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (!(e instanceof ExactReadableEndedError)) {
|
||||
|
@ -179,20 +179,18 @@ export class Struct<
|
|||
}
|
||||
}
|
||||
|
||||
if (this.extra) {
|
||||
Object.defineProperties(
|
||||
runtimeStruct,
|
||||
Object.getOwnPropertyDescriptors(this.extra),
|
||||
);
|
||||
if (extra) {
|
||||
Object.defineProperties(runtimeStruct, extra);
|
||||
}
|
||||
|
||||
if (this.postDeserialize) {
|
||||
return this.postDeserialize.call(
|
||||
runtimeStruct,
|
||||
if (options.postDeserialize) {
|
||||
return options.postDeserialize.call(
|
||||
runtimeStruct as never,
|
||||
runtimeStruct as never,
|
||||
);
|
||||
} else {
|
||||
return runtimeStruct as never;
|
||||
return runtimeStruct;
|
||||
}
|
||||
}) as never;
|
||||
}),
|
||||
} as never;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue