mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-05 10:49:24 +02:00
refactor(struct): improve tree-shaking
This commit is contained in:
parent
70b0d3e5d8
commit
c1dc802364
15 changed files with 102 additions and 93 deletions
|
@ -34,7 +34,7 @@ export type AdbShellProtocolId =
|
||||||
// This packet format is used in both directions.
|
// This packet format is used in both directions.
|
||||||
export const AdbShellProtocolPacket = struct(
|
export const AdbShellProtocolPacket = struct(
|
||||||
{
|
{
|
||||||
id: u8.as<AdbShellProtocolId>(),
|
id: u8<AdbShellProtocolId>(),
|
||||||
data: buffer(u32),
|
data: buffer(u32),
|
||||||
},
|
},
|
||||||
{ littleEndian: true },
|
{ littleEndian: true },
|
||||||
|
|
|
@ -115,7 +115,7 @@ export interface AdbSyncPushV2Options extends AdbSyncPushV1Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AdbSyncSendV2Request = struct(
|
export const AdbSyncSendV2Request = struct(
|
||||||
{ id: u32, mode: u32, flags: u32.as<AdbSyncSendV2Flags>() },
|
{ id: u32, mode: u32, flags: u32<AdbSyncSendV2Flags>() },
|
||||||
{ littleEndian: true },
|
{ littleEndian: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -77,18 +77,17 @@ export const AdbSyncStatErrorCode = {
|
||||||
export type AdbSyncStatErrorCode =
|
export type AdbSyncStatErrorCode =
|
||||||
(typeof AdbSyncStatErrorCode)[keyof typeof AdbSyncStatErrorCode];
|
(typeof AdbSyncStatErrorCode)[keyof typeof AdbSyncStatErrorCode];
|
||||||
|
|
||||||
const AdbSyncStatErrorName =
|
const AdbSyncStatErrorName = /* #__PURE__ */ (() =>
|
||||||
/* #__PURE__ */
|
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
Object.entries(AdbSyncStatErrorCode).map(([key, value]) => [
|
Object.entries(AdbSyncStatErrorCode).map(([key, value]) => [
|
||||||
value,
|
value,
|
||||||
key,
|
key,
|
||||||
]),
|
]),
|
||||||
);
|
))();
|
||||||
|
|
||||||
export const AdbSyncStatResponse = struct(
|
export const AdbSyncStatResponse = struct(
|
||||||
{
|
{
|
||||||
error: u32.as<AdbSyncStatErrorCode>(),
|
error: u32<AdbSyncStatErrorCode>(),
|
||||||
dev: u64,
|
dev: u64,
|
||||||
ino: u64,
|
ino: u64,
|
||||||
mode: u32,
|
mode: u32,
|
||||||
|
|
|
@ -209,10 +209,10 @@ export enum AndroidKeyCode {
|
||||||
export const ScrcpyInjectKeyCodeControlMessage = struct(
|
export const ScrcpyInjectKeyCodeControlMessage = struct(
|
||||||
{
|
{
|
||||||
type: u8,
|
type: u8,
|
||||||
action: u8.as<AndroidKeyEventAction>(),
|
action: u8<AndroidKeyEventAction>(),
|
||||||
keyCode: u32.as<AndroidKeyCode>(),
|
keyCode: u32<AndroidKeyCode>(),
|
||||||
repeat: u32,
|
repeat: u32,
|
||||||
metaState: u32.as<AndroidKeyEventMeta>(),
|
metaState: u32<AndroidKeyEventMeta>(),
|
||||||
},
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,7 @@ export type AndroidScreenPowerMode =
|
||||||
(typeof AndroidScreenPowerMode)[keyof typeof AndroidScreenPowerMode];
|
(typeof AndroidScreenPowerMode)[keyof typeof AndroidScreenPowerMode];
|
||||||
|
|
||||||
export const ScrcpySetScreenPowerModeControlMessage = struct(
|
export const ScrcpySetScreenPowerModeControlMessage = struct(
|
||||||
{ type: u8, mode: u8.as<AndroidScreenPowerMode>() },
|
{ type: u8, mode: u8<AndroidScreenPowerMode>() },
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ export const SCRCPY_MEDIA_PACKET_FLAG_CONFIG = 1n << 63n;
|
||||||
export const ScrcpyInjectTouchControlMessage1_16 = struct(
|
export const ScrcpyInjectTouchControlMessage1_16 = struct(
|
||||||
{
|
{
|
||||||
type: u8,
|
type: u8,
|
||||||
action: u8.as<AndroidMotionEventAction>(),
|
action: u8<AndroidMotionEventAction>(),
|
||||||
pointerId: u64,
|
pointerId: u64,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
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 type { ScrcpyInjectScrollControlMessage } from "../../control/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../control/index.js";
|
|
||||||
|
|
||||||
export interface ScrcpyScrollController {
|
export interface ScrcpyScrollController {
|
||||||
serializeScrollMessage(
|
serializeScrollMessage(
|
||||||
|
@ -11,7 +10,7 @@ export interface ScrcpyScrollController {
|
||||||
|
|
||||||
export const ScrcpyInjectScrollControlMessage1_16 = struct(
|
export const ScrcpyInjectScrollControlMessage1_16 = struct(
|
||||||
{
|
{
|
||||||
type: u8.as(ScrcpyControlMessageType.InjectScroll as const),
|
type: u8,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
screenWidth: u16,
|
screenWidth: u16,
|
||||||
|
|
|
@ -48,7 +48,7 @@ export interface ScrcpyOptionsInit1_18
|
||||||
export const ScrcpyBackOrScreenOnControlMessage1_18 = struct(
|
export const ScrcpyBackOrScreenOnControlMessage1_18 = struct(
|
||||||
/* #__PURE__ */ (() => ({
|
/* #__PURE__ */ (() => ({
|
||||||
...ScrcpyBackOrScreenOnControlMessage1_16.fields,
|
...ScrcpyBackOrScreenOnControlMessage1_16.fields,
|
||||||
action: u8.as<AndroidKeyEventAction>(),
|
action: u8<AndroidKeyEventAction>(),
|
||||||
}))(),
|
}))(),
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
);
|
);
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const ScrcpySetClipboardControlMessage1_21 = struct(
|
||||||
{
|
{
|
||||||
type: u8,
|
type: u8,
|
||||||
sequence: u64,
|
sequence: u64,
|
||||||
paste: u8.as<boolean>(),
|
paste: u8<boolean>(),
|
||||||
content: string(u32),
|
content: string(u32),
|
||||||
},
|
},
|
||||||
{ littleEndian: false },
|
{ littleEndian: false },
|
||||||
|
|
|
@ -3,7 +3,6 @@ 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 type { ScrcpyInjectScrollControlMessage } from "../../control/index.js";
|
||||||
import { ScrcpyControlMessageType } from "../../control/index.js";
|
|
||||||
import type { ScrcpyScrollController } from "../1_16/index.js";
|
import type { ScrcpyScrollController } from "../1_16/index.js";
|
||||||
import { clamp } from "../1_16/index.js";
|
import { clamp } from "../1_16/index.js";
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ export const ScrcpySignedFloat: Field<number, never, never> = {
|
||||||
|
|
||||||
export const ScrcpyInjectScrollControlMessage1_25 = struct(
|
export const ScrcpyInjectScrollControlMessage1_25 = struct(
|
||||||
{
|
{
|
||||||
type: u8.as(ScrcpyControlMessageType.InjectScroll as const),
|
type: u8,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
screenWidth: u16,
|
screenWidth: u16,
|
||||||
|
|
|
@ -33,7 +33,7 @@ import { ScrcpyOptions } from "./types.js";
|
||||||
export const ScrcpyInjectTouchControlMessage2_0 = struct(
|
export const ScrcpyInjectTouchControlMessage2_0 = struct(
|
||||||
{
|
{
|
||||||
type: u8,
|
type: u8,
|
||||||
action: u8.as<AndroidMotionEventAction>(),
|
action: u8<AndroidMotionEventAction>(),
|
||||||
pointerId: u64,
|
pointerId: u64,
|
||||||
pointerX: u32,
|
pointerX: u32,
|
||||||
pointerY: u32,
|
pointerY: u32,
|
||||||
|
|
|
@ -12,10 +12,10 @@ interface GlobalExtension {
|
||||||
|
|
||||||
// `createTask` allows browser DevTools to track the call stack across async boundaries.
|
// `createTask` allows browser DevTools to track the call stack across async boundaries.
|
||||||
const { console } = globalThis as unknown as GlobalExtension;
|
const { console } = globalThis as unknown as GlobalExtension;
|
||||||
export const createTask: (name: string) => Task =
|
export const createTask: (name: string) => Task = /* #__PURE__ */ (() =>
|
||||||
console?.createTask?.bind(console) ??
|
console?.createTask?.bind(console) ??
|
||||||
(() => ({
|
(() => ({
|
||||||
run(callback) {
|
run(callback) {
|
||||||
return callback();
|
return callback();
|
||||||
},
|
},
|
||||||
}));
|
})))();
|
||||||
|
|
|
@ -42,7 +42,7 @@ export interface BufferLike {
|
||||||
|
|
||||||
export const EmptyUint8Array = new Uint8Array(0);
|
export const EmptyUint8Array = new Uint8Array(0);
|
||||||
|
|
||||||
// This is required for Rollup tree-shaking to work.
|
// Rollup doesn't support `/* #__NO_SIDE_EFFECTS__ */ export const a = () => {}
|
||||||
/* #__NO_SIDE_EFFECTS__ */
|
/* #__NO_SIDE_EFFECTS__ */
|
||||||
function _buffer(
|
function _buffer(
|
||||||
lengthOrField:
|
lengthOrField:
|
||||||
|
@ -54,16 +54,27 @@ function _buffer(
|
||||||
): Field<unknown, string, Record<string, unknown>> {
|
): Field<unknown, string, Record<string, unknown>> {
|
||||||
if (typeof lengthOrField === "number") {
|
if (typeof lengthOrField === "number") {
|
||||||
if (converter) {
|
if (converter) {
|
||||||
|
if (lengthOrField === 0) {
|
||||||
|
return {
|
||||||
|
size: 0,
|
||||||
|
serialize: () => {},
|
||||||
|
deserialize: () => converter.convert(EmptyUint8Array),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
size: lengthOrField,
|
size: lengthOrField,
|
||||||
serialize: (value, { buffer, index }) => {
|
serialize: (value, { buffer, index }) => {
|
||||||
buffer.set(converter.back(value), index);
|
buffer.set(
|
||||||
|
converter.back(value).slice(0, lengthOrField),
|
||||||
|
index,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader }) {
|
deserialize: bipedal(function* (then, { reader }) {
|
||||||
const value = yield* then(
|
const array = yield* then(
|
||||||
reader.readExactly(lengthOrField),
|
reader.readExactly(lengthOrField),
|
||||||
);
|
);
|
||||||
return converter.convert(value);
|
return converter.convert(array);
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -79,13 +90,21 @@ function _buffer(
|
||||||
return {
|
return {
|
||||||
size: lengthOrField,
|
size: lengthOrField,
|
||||||
serialize: (value, { buffer, index }) => {
|
serialize: (value, { buffer, index }) => {
|
||||||
buffer.set(value as Uint8Array, index);
|
buffer.set(
|
||||||
|
(value as Uint8Array).slice(0, lengthOrField),
|
||||||
|
index,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
deserialize: ({ reader }) => reader.readExactly(lengthOrField),
|
deserialize: ({ reader }) => reader.readExactly(lengthOrField),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof lengthOrField === "object" && "serialize" in lengthOrField) {
|
// Some Field type might be `function`s
|
||||||
|
if (
|
||||||
|
(typeof lengthOrField === "object" ||
|
||||||
|
typeof lengthOrField === "function") &&
|
||||||
|
"serialize" in lengthOrField
|
||||||
|
) {
|
||||||
if (converter) {
|
if (converter) {
|
||||||
return {
|
return {
|
||||||
size: 0,
|
size: 0,
|
||||||
|
@ -108,10 +127,10 @@ function _buffer(
|
||||||
const length = yield* then(
|
const length = yield* then(
|
||||||
lengthOrField.deserialize(context),
|
lengthOrField.deserialize(context),
|
||||||
);
|
);
|
||||||
const value = yield* then(
|
const array = yield* then(
|
||||||
context.reader.readExactly(length),
|
context.reader.readExactly(length),
|
||||||
);
|
);
|
||||||
return converter.convert(value);
|
return converter.convert(array);
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,114 +17,107 @@ import {
|
||||||
import { bipedal } from "./bipedal.js";
|
import { bipedal } from "./bipedal.js";
|
||||||
import type { Field } from "./field.js";
|
import type { Field } from "./field.js";
|
||||||
|
|
||||||
export const u8: Field<number, never, never> & {
|
export interface NumberField<T> extends Field<T, never, never> {
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
<U>(infer?: T): Field<U, never, never>;
|
||||||
} = {
|
}
|
||||||
size: 1,
|
|
||||||
serialize(value, { buffer, index }) {
|
/* #__NO_SIDE_EFFECTS__ */
|
||||||
|
function number<T>(
|
||||||
|
size: number,
|
||||||
|
serialize: Field<T, never, never>["serialize"],
|
||||||
|
deserialize: Field<T, never, never>["deserialize"],
|
||||||
|
): NumberField<T> {
|
||||||
|
const result = () => result;
|
||||||
|
result.size = size;
|
||||||
|
result.serialize = serialize;
|
||||||
|
result.deserialize = deserialize;
|
||||||
|
return result as never;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const u8 = number<number>(
|
||||||
|
1,
|
||||||
|
(value, { buffer, index }) => {
|
||||||
buffer[index] = value;
|
buffer[index] = value;
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader }) {
|
bipedal(function* (then, { reader }) {
|
||||||
const data = yield* then(reader.readExactly(1));
|
const data = yield* then(reader.readExactly(1));
|
||||||
return data[0]!;
|
return data[0]!;
|
||||||
}),
|
}),
|
||||||
as: () => u8 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const s8: Field<number, never, never> & {
|
export const s8 = number<number>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
1,
|
||||||
} = {
|
(value, { buffer, index }) => {
|
||||||
size: 1,
|
|
||||||
serialize(value, { buffer, index }) {
|
|
||||||
buffer[index] = value;
|
buffer[index] = value;
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader }) {
|
bipedal(function* (then, { reader }) {
|
||||||
const data = yield* then(reader.readExactly(1));
|
const data = yield* then(reader.readExactly(1));
|
||||||
return getInt8(data, 0);
|
return getInt8(data, 0);
|
||||||
}),
|
}),
|
||||||
as: () => s8 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const u16: Field<number, never, never> & {
|
export const u16 = number<number>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
2,
|
||||||
} = {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
size: 2,
|
|
||||||
serialize(value, { buffer, index, littleEndian }) {
|
|
||||||
setUint16(buffer, index, value, littleEndian);
|
setUint16(buffer, index, value, littleEndian);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader, littleEndian }) {
|
bipedal(function* (then, { reader, littleEndian }) {
|
||||||
const data = yield* then(reader.readExactly(2));
|
const data = yield* then(reader.readExactly(2));
|
||||||
return getUint16(data, 0, littleEndian);
|
return getUint16(data, 0, littleEndian);
|
||||||
}),
|
}),
|
||||||
as: () => u16 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const s16: Field<number, never, never> & {
|
export const s16 = number<number>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
2,
|
||||||
} = {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
size: 2,
|
|
||||||
serialize(value, { buffer, index, littleEndian }) {
|
|
||||||
setInt16(buffer, index, value, littleEndian);
|
setInt16(buffer, index, value, littleEndian);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader, littleEndian }) {
|
bipedal(function* (then, { reader, littleEndian }) {
|
||||||
const data = yield* then(reader.readExactly(2));
|
const data = yield* then(reader.readExactly(2));
|
||||||
return getInt16(data, 0, littleEndian);
|
return getInt16(data, 0, littleEndian);
|
||||||
}),
|
}),
|
||||||
as: () => s16 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const u32: Field<number, never, never> & {
|
export const u32 = number<number>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
4,
|
||||||
} = {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
size: 4,
|
|
||||||
serialize(value, { buffer, index, littleEndian }) {
|
|
||||||
setUint32(buffer, index, value, littleEndian);
|
setUint32(buffer, index, value, littleEndian);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader, littleEndian }) {
|
bipedal(function* (then, { reader, littleEndian }) {
|
||||||
const data = yield* then(reader.readExactly(4));
|
const data = yield* then(reader.readExactly(4));
|
||||||
return getUint32(data, 0, littleEndian);
|
return getUint32(data, 0, littleEndian);
|
||||||
}),
|
}),
|
||||||
as: () => u32 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const s32: Field<number, never, never> & {
|
export const s32 = number<number>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
4,
|
||||||
} = {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
size: 4,
|
|
||||||
serialize(value, { buffer, index, littleEndian }) {
|
|
||||||
setInt32(buffer, index, value, littleEndian);
|
setInt32(buffer, index, value, littleEndian);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader, littleEndian }) {
|
bipedal(function* (then, { reader, littleEndian }) {
|
||||||
const data = yield* then(reader.readExactly(4));
|
const data = yield* then(reader.readExactly(4));
|
||||||
return getInt32(data, 0, littleEndian);
|
return getInt32(data, 0, littleEndian);
|
||||||
}),
|
}),
|
||||||
as: () => s32 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const u64: Field<bigint, never, never> & {
|
export const u64 = number<bigint>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
8,
|
||||||
} = {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
size: 8,
|
|
||||||
serialize(value, { buffer, index, littleEndian }) {
|
|
||||||
setUint64(buffer, index, value, littleEndian);
|
setUint64(buffer, index, value, littleEndian);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader, littleEndian }) {
|
bipedal(function* (then, { reader, littleEndian }) {
|
||||||
const data = yield* then(reader.readExactly(8));
|
const data = yield* then(reader.readExactly(8));
|
||||||
return getUint64(data, 0, littleEndian);
|
return getUint64(data, 0, littleEndian);
|
||||||
}),
|
}),
|
||||||
as: () => u64 as never,
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export const s64: Field<bigint, never, never> & {
|
export const s64 = number<bigint>(
|
||||||
as: <T>(infer?: T) => Field<T, never, never>;
|
8,
|
||||||
} = {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
size: 8,
|
|
||||||
serialize(value, { buffer, index, littleEndian }) {
|
|
||||||
setInt64(buffer, index, value, littleEndian);
|
setInt64(buffer, index, value, littleEndian);
|
||||||
},
|
},
|
||||||
deserialize: bipedal(function* (then, { reader, littleEndian }) {
|
bipedal(function* (then, { reader, littleEndian }) {
|
||||||
const data = yield* then(reader.readExactly(8));
|
const data = yield* then(reader.readExactly(8));
|
||||||
return getInt64(data, 0, littleEndian);
|
return getInt64(data, 0, littleEndian);
|
||||||
}),
|
}),
|
||||||
as: () => s64 as never,
|
);
|
||||||
};
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ export interface String {
|
||||||
): Field<string, KOmitInit, KS>;
|
): Field<string, KOmitInit, KS>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is required for Rollup tree-shaking to work.
|
// Rollup doesn't support `/* #__NO_SIDE_EFFECTS__ */ export const a = () => {}
|
||||||
/* #__NO_SIDE_EFFECTS__ */
|
/* #__NO_SIDE_EFFECTS__ */
|
||||||
function _string(
|
function _string(
|
||||||
lengthOrField: string | number | BufferLengthConverter<string, unknown>,
|
lengthOrField: string | number | BufferLengthConverter<string, unknown>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue