diff --git a/.changeset/clean-moons-obey.md b/.changeset/clean-moons-obey.md new file mode 100644 index 00000000..3ec51972 --- /dev/null +++ b/.changeset/clean-moons-obey.md @@ -0,0 +1,7 @@ +--- +"@yume-chan/scrcpy": major +--- + +Convert `ScrcpyOptionsX_YY.prototype.controlMessageTypes` to a mapping from internal control message types to version-specific values. + +Generally, `ScrcpyControlMessageSerializer`, `ScrcpyControlMessageWriter`, or `AdbScrcpyClient.prototype.controller` should be used to send control messages to devices, instead of using `controlMessageTypes` directly. diff --git a/libraries/adb-daemon-webusb/src/device.ts b/libraries/adb-daemon-webusb/src/device.ts index 31cab37c..51e107f7 100644 --- a/libraries/adb-daemon-webusb/src/device.ts +++ b/libraries/adb-daemon-webusb/src/device.ts @@ -143,16 +143,6 @@ export class AdbDaemonWebUsbConnection new MaybeConsumable.WritableStream({ write: async (chunk) => { try { - if ( - typeof SharedArrayBuffer !== "undefined" && - chunk.buffer instanceof SharedArrayBuffer - ) { - // Copy data to a non-shared ArrayBuffer - const copy = new Uint8Array(chunk.byteLength); - copy.set(chunk); - chunk = copy; - } - await device.raw.transferOut( outEndpoint.endpointNumber, // WebUSB doesn't support SharedArrayBuffer diff --git a/libraries/adb-scrcpy/src/3_3_2.ts b/libraries/adb-scrcpy/src/3_3_2.ts index 559d04c0..a926d6aa 100644 --- a/libraries/adb-scrcpy/src/3_3_2.ts +++ b/libraries/adb-scrcpy/src/3_3_2.ts @@ -27,7 +27,7 @@ export class AdbScrcpyOptions3_3_2 ) { super(init); - this.version = clientOptions?.version ?? "3.3.1"; + this.version = clientOptions?.version ?? "3.3.2"; this.spawner = clientOptions?.spawner; } diff --git a/libraries/adb/src/utils/array-buffer.ts b/libraries/adb/src/utils/array-buffer.ts index 7d6cc98f..981f696b 100644 --- a/libraries/adb/src/utils/array-buffer.ts +++ b/libraries/adb/src/utils/array-buffer.ts @@ -3,7 +3,5 @@ export function toLocalUint8Array(value: Uint8Array): Uint8Array { return value as Uint8Array; } - const copy = new Uint8Array(value.length); - copy.set(value); - return copy; + return new Uint8Array(value); } diff --git a/libraries/media-codec/src/h265.ts b/libraries/media-codec/src/h265.ts index fb5c4eff..a9daf3b1 100644 --- a/libraries/media-codec/src/h265.ts +++ b/libraries/media-codec/src/h265.ts @@ -862,21 +862,21 @@ export function parseShortTermReferencePictureSet( export const AspectRatioIndicator = { Unspecified: 0, Square: 1, - _12_11: 2, - _10_11: 3, - _16_11: 4, - _40_33: 5, - _24_11: 6, - _20_11: 7, - _32_11: 8, - _80_33: 9, - _18_11: 10, - _15_11: 11, - _64_33: 12, - _160_99: 13, - _4_3: 15, - _3_2: 16, - _2_1: 17, + ["12:11"]: 2, + ["10:11"]: 3, + ["16:11"]: 4, + ["40:33"]: 5, + ["24:11"]: 6, + ["20:11"]: 7, + ["32:11"]: 8, + ["80:33"]: 9, + ["18:11"]: 10, + ["15:11"]: 11, + ["64:33"]: 12, + ["160:99"]: 13, + ["4:3"]: 15, + ["3:2"]: 16, + ["2:1"]: 17, Extended: 255, } as const; diff --git a/libraries/scrcpy/src/1_15/impl/control-message-types.ts b/libraries/scrcpy/src/1_15/impl/control-message-types.ts index 58da9daa..01ab59b5 100644 --- a/libraries/scrcpy/src/1_15/impl/control-message-types.ts +++ b/libraries/scrcpy/src/1_15/impl/control-message-types.ts @@ -1,16 +1,16 @@ +import type { ScrcpyControlMessageTypeMap } from "../../base/index.js"; import { ScrcpyControlMessageType } from "../../base/index.js"; -export const ControlMessageTypes: readonly ScrcpyControlMessageType[] = - /* #__PURE__ */ (() => [ - /* 0 */ ScrcpyControlMessageType.InjectKeyCode, - /* 1 */ ScrcpyControlMessageType.InjectText, - /* 2 */ ScrcpyControlMessageType.InjectTouch, - /* 3 */ ScrcpyControlMessageType.InjectScroll, - /* 4 */ ScrcpyControlMessageType.BackOrScreenOn, - /* 5 */ ScrcpyControlMessageType.ExpandNotificationPanel, - /* 6 */ ScrcpyControlMessageType.CollapseNotificationPanel, - /* 7 */ ScrcpyControlMessageType.GetClipboard, - /* 8 */ ScrcpyControlMessageType.SetClipboard, - /* 9 */ ScrcpyControlMessageType.SetDisplayPower, - /* 10 */ ScrcpyControlMessageType.RotateDevice, - ])(); +export const ControlMessageTypes = { + [ScrcpyControlMessageType.InjectKeyCode]: 0, + [ScrcpyControlMessageType.InjectText]: 1, + [ScrcpyControlMessageType.InjectTouch]: 2, + [ScrcpyControlMessageType.InjectScroll]: 3, + [ScrcpyControlMessageType.BackOrScreenOn]: 4, + [ScrcpyControlMessageType.ExpandNotificationPanel]: 5, + [ScrcpyControlMessageType.CollapseNotificationPanel]: 6, + [ScrcpyControlMessageType.GetClipboard]: 7, + [ScrcpyControlMessageType.SetClipboard]: 8, + [ScrcpyControlMessageType.SetDisplayPower]: 9, + [ScrcpyControlMessageType.RotateDevice]: 10, +} as const satisfies ScrcpyControlMessageTypeMap; diff --git a/libraries/scrcpy/src/1_15/impl/inject-touch.ts b/libraries/scrcpy/src/1_15/impl/inject-touch.ts index 68e8f5ec..3c6a91ba 100644 --- a/libraries/scrcpy/src/1_15/impl/inject-touch.ts +++ b/libraries/scrcpy/src/1_15/impl/inject-touch.ts @@ -32,6 +32,7 @@ export const PointerId = { export const InjectTouchControlMessage = struct( { + // value of `type` can change between versions type: u8, action: u8(), pointerId: u64, diff --git a/libraries/scrcpy/src/1_15/impl/scroll-controller.ts b/libraries/scrcpy/src/1_15/impl/scroll-controller.ts index 465f2750..ba7df956 100644 --- a/libraries/scrcpy/src/1_15/impl/scroll-controller.ts +++ b/libraries/scrcpy/src/1_15/impl/scroll-controller.ts @@ -6,6 +6,7 @@ import type { ScrcpyInjectScrollControlMessage } from "../../latest.js"; export const InjectScrollControlMessage = struct( { + // value of `type` can change between versions type: u8, pointerX: u32, pointerY: u32, diff --git a/libraries/scrcpy/src/1_15/impl/set-clipboard.ts b/libraries/scrcpy/src/1_15/impl/set-clipboard.ts index 5df98b71..3cef70a3 100644 --- a/libraries/scrcpy/src/1_15/impl/set-clipboard.ts +++ b/libraries/scrcpy/src/1_15/impl/set-clipboard.ts @@ -4,7 +4,11 @@ import { string, struct, u32, u8 } from "@yume-chan/struct"; import type { ScrcpySetClipboardControlMessage } from "../../latest.js"; export const SetClipboardControlMessage = struct( - { type: u8, content: string(u32) }, + { + // value of `type` can change between versions + type: u8, + content: string(u32), + }, { littleEndian: false }, ); diff --git a/libraries/scrcpy/src/1_15/options.ts b/libraries/scrcpy/src/1_15/options.ts index 0cc348e4..c48e5139 100644 --- a/libraries/scrcpy/src/1_15/options.ts +++ b/libraries/scrcpy/src/1_15/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyMediaStreamPacket, ScrcpyOptions, @@ -38,7 +37,7 @@ export class ScrcpyOptions1_15 implements ScrcpyOptions { readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } diff --git a/libraries/scrcpy/src/1_15_1.ts b/libraries/scrcpy/src/1_15_1.ts index b15067a0..0cba2521 100644 --- a/libraries/scrcpy/src/1_15_1.ts +++ b/libraries/scrcpy/src/1_15_1.ts @@ -1,11 +1 @@ -import { ScrcpyOptions1_15 } from "./1_15/index.js"; - -export class ScrcpyOptions1_15_1 extends ScrcpyOptions1_15 { - constructor(init: ScrcpyOptions1_15.Init) { - super(init); - } -} - -export namespace ScrcpyOptions1_15_1 { - export type Init = ScrcpyOptions1_15.Init; -} +export { ScrcpyOptions1_15 as ScrcpyOptions1_15_1 } from "./1_15/index.js"; diff --git a/libraries/scrcpy/src/1_16.ts b/libraries/scrcpy/src/1_16.ts index e1b6cd12..1c79d7ad 100644 --- a/libraries/scrcpy/src/1_16.ts +++ b/libraries/scrcpy/src/1_16.ts @@ -1,11 +1 @@ -import { ScrcpyOptions1_15 } from "./1_15/index.js"; - -export class ScrcpyOptions1_16 extends ScrcpyOptions1_15 { - constructor(init: ScrcpyOptions1_15.Init) { - super(init); - } -} - -export namespace ScrcpyOptions1_16 { - export type Init = ScrcpyOptions1_15.Init; -} +export { ScrcpyOptions1_15 as ScrcpyOptions1_16 } from "./1_15/index.js"; diff --git a/libraries/scrcpy/src/1_17/impl/defaults.ts b/libraries/scrcpy/src/1_17/impl/defaults.ts index 05bff962..4cf98ea8 100644 --- a/libraries/scrcpy/src/1_17/impl/defaults.ts +++ b/libraries/scrcpy/src/1_17/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - encoderName: undefined, - }) as const satisfies Required)(); +export const Defaults = { + ...PrevImpl.Defaults, + encoderName: undefined, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/1_17/options.ts b/libraries/scrcpy/src/1_17/options.ts index 9cab6e48..ec8af85f 100644 --- a/libraries/scrcpy/src/1_17/options.ts +++ b/libraries/scrcpy/src/1_17/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -45,7 +44,7 @@ export class ScrcpyOptions1_17 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } diff --git a/libraries/scrcpy/src/1_18/impl/control-message-types.ts b/libraries/scrcpy/src/1_18/impl/control-message-types.ts index df3a9b28..8d28273f 100644 --- a/libraries/scrcpy/src/1_18/impl/control-message-types.ts +++ b/libraries/scrcpy/src/1_18/impl/control-message-types.ts @@ -1,10 +1,17 @@ +import type { ScrcpyControlMessageTypeMap } from "../../base/index.js"; import { ScrcpyControlMessageType } from "../../base/index.js"; -import { PrevImpl } from "./prev.js"; - -export const ControlMessageTypes: readonly ScrcpyControlMessageType[] = - /* #__PURE__ */ (() => { - const result = PrevImpl.ControlMessageTypes.slice(); - result.splice(6, 0, ScrcpyControlMessageType.ExpandSettingPanel); - return result; - })(); +export const ControlMessageTypes = { + [ScrcpyControlMessageType.InjectKeyCode]: 0, + [ScrcpyControlMessageType.InjectText]: 1, + [ScrcpyControlMessageType.InjectTouch]: 2, + [ScrcpyControlMessageType.InjectScroll]: 3, + [ScrcpyControlMessageType.BackOrScreenOn]: 4, + [ScrcpyControlMessageType.ExpandNotificationPanel]: 5, + [ScrcpyControlMessageType.ExpandSettingPanel]: 6, + [ScrcpyControlMessageType.CollapseNotificationPanel]: 7, + [ScrcpyControlMessageType.GetClipboard]: 8, + [ScrcpyControlMessageType.SetClipboard]: 9, + [ScrcpyControlMessageType.SetDisplayPower]: 10, + [ScrcpyControlMessageType.RotateDevice]: 11, +} as const satisfies ScrcpyControlMessageTypeMap; diff --git a/libraries/scrcpy/src/1_18/impl/defaults.ts b/libraries/scrcpy/src/1_18/impl/defaults.ts index 81f8736a..a5255ea9 100644 --- a/libraries/scrcpy/src/1_18/impl/defaults.ts +++ b/libraries/scrcpy/src/1_18/impl/defaults.ts @@ -2,10 +2,9 @@ import type { Init } from "./init.js"; import { VideoOrientation } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - logLevel: "debug", - lockVideoOrientation: VideoOrientation.Unlocked, - powerOffOnClose: false, - }) as const satisfies Required)(); +export const Defaults = { + ...PrevImpl.Defaults, + logLevel: "debug", + lockVideoOrientation: VideoOrientation.Unlocked, + powerOffOnClose: false, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/1_18/options.ts b/libraries/scrcpy/src/1_18/options.ts index 96c57273..c2e1ec3d 100644 --- a/libraries/scrcpy/src/1_18/options.ts +++ b/libraries/scrcpy/src/1_18/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -45,7 +44,7 @@ export class ScrcpyOptions1_18 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } diff --git a/libraries/scrcpy/src/1_19.ts b/libraries/scrcpy/src/1_19.ts index da95ebe9..e0f5fb04 100644 --- a/libraries/scrcpy/src/1_19.ts +++ b/libraries/scrcpy/src/1_19.ts @@ -1,11 +1 @@ -import { ScrcpyOptions1_18 } from "./1_18/index.js"; - -export class ScrcpyOptions1_19 extends ScrcpyOptions1_18 { - constructor(init: ScrcpyOptions1_18.Init) { - super(init); - } -} - -export namespace ScrcpyOptions1_19 { - export type Init = ScrcpyOptions1_18.Init; -} +export { ScrcpyOptions1_18 as ScrcpyOptions1_19 } from "./1_18/index.js"; diff --git a/libraries/scrcpy/src/1_20.ts b/libraries/scrcpy/src/1_20.ts index 32b5948b..1da5b910 100644 --- a/libraries/scrcpy/src/1_20.ts +++ b/libraries/scrcpy/src/1_20.ts @@ -1,11 +1 @@ -import { ScrcpyOptions1_18 } from "./1_18/index.js"; - -export class ScrcpyOptions1_20 extends ScrcpyOptions1_18 { - constructor(init: ScrcpyOptions1_18.Init) { - super(init); - } -} - -export namespace ScrcpyOptions1_20 { - export type Init = ScrcpyOptions1_18.Init; -} +export { ScrcpyOptions1_18 as ScrcpyOptions1_20 } from "./1_18/index.js"; diff --git a/libraries/scrcpy/src/1_21/impl/defaults.ts b/libraries/scrcpy/src/1_21/impl/defaults.ts index 492dd022..4e406243 100644 --- a/libraries/scrcpy/src/1_21/impl/defaults.ts +++ b/libraries/scrcpy/src/1_21/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - clipboardAutosync: true, - }) as const satisfies Required)(); +export const Defaults = { + ...PrevImpl.Defaults, + clipboardAutosync: true, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/1_21/impl/index.ts b/libraries/scrcpy/src/1_21/impl/index.ts index 3e9646ca..1d160ee2 100644 --- a/libraries/scrcpy/src/1_21/impl/index.ts +++ b/libraries/scrcpy/src/1_21/impl/index.ts @@ -7,4 +7,5 @@ export { AckClipboardDeviceMessage, AckClipboardHandler, SetClipboardControlMessage, + serializeSetClipboardControlMessage, } from "./set-clipboard.js"; diff --git a/libraries/scrcpy/src/1_21/impl/set-clipboard.ts b/libraries/scrcpy/src/1_21/impl/set-clipboard.ts index b740e76a..a91c2d44 100644 --- a/libraries/scrcpy/src/1_21/impl/set-clipboard.ts +++ b/libraries/scrcpy/src/1_21/impl/set-clipboard.ts @@ -12,6 +12,7 @@ export const AckClipboardDeviceMessage = struct( export const SetClipboardControlMessage = struct( { + // value of `type` can change between versions type: u8, sequence: u64, paste: u8(), @@ -75,3 +76,16 @@ export class AckClipboardHandler implements ScrcpyDeviceMessageParser { ]; } } + +export function serializeSetClipboardControlMessage( + message: ScrcpySetClipboardControlMessage, + ackHandler: AckClipboardHandler | undefined, +): Uint8Array | [Uint8Array, Promise] { + if (!ackHandler) { + throw new Error( + "`serializeSetClipboardControlMessage` requires `control: true` option", + ); + } + + return ackHandler.serializeSetClipboardControlMessage(message); +} diff --git a/libraries/scrcpy/src/1_21/options.ts b/libraries/scrcpy/src/1_21/options.ts index 8b9a42a5..786c7cda 100644 --- a/libraries/scrcpy/src/1_21/options.ts +++ b/libraries/scrcpy/src/1_21/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -33,6 +32,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -44,7 +44,7 @@ export class ScrcpyOptions1_21 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -63,10 +63,12 @@ export class ScrcpyOptions1_21 constructor(init: Init) { this.value = { ...Defaults, ...init }; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -122,8 +124,9 @@ export class ScrcpyOptions1_21 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/1_22/impl/defaults.ts b/libraries/scrcpy/src/1_22/impl/defaults.ts index 6b4fdee8..d000c018 100644 --- a/libraries/scrcpy/src/1_22/impl/defaults.ts +++ b/libraries/scrcpy/src/1_22/impl/defaults.ts @@ -1,10 +1,9 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - downsizeOnError: true, - sendDeviceMeta: true, - sendDummyByte: true, - }) as const satisfies Required)(); +export const Defaults = { + ...PrevImpl.Defaults, + downsizeOnError: true, + sendDeviceMeta: true, + sendDummyByte: true, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/1_22/options.ts b/libraries/scrcpy/src/1_22/options.ts index 88938b47..7f0ff172 100644 --- a/libraries/scrcpy/src/1_22/options.ts +++ b/libraries/scrcpy/src/1_22/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -33,6 +32,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -44,7 +44,7 @@ export class ScrcpyOptions1_22 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -63,10 +63,12 @@ export class ScrcpyOptions1_22 constructor(init: Init) { this.value = { ...Defaults, ...init }; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -122,8 +124,9 @@ export class ScrcpyOptions1_22 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/1_23/impl/defaults.ts b/libraries/scrcpy/src/1_23/impl/defaults.ts index b9781824..1286370e 100644 --- a/libraries/scrcpy/src/1_23/impl/defaults.ts +++ b/libraries/scrcpy/src/1_23/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - cleanup: true, - }) as const satisfies Required)(); +export const Defaults = { + ...PrevImpl.Defaults, + cleanup: true, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/1_23/options.ts b/libraries/scrcpy/src/1_23/options.ts index 026a364e..769b89d8 100644 --- a/libraries/scrcpy/src/1_23/options.ts +++ b/libraries/scrcpy/src/1_23/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -33,6 +32,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -44,7 +44,7 @@ export class ScrcpyOptions1_23 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -63,10 +63,12 @@ export class ScrcpyOptions1_23 constructor(init: Init) { this.value = { ...Defaults, ...init }; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -122,8 +124,9 @@ export class ScrcpyOptions1_23 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/1_24/impl/defaults.ts b/libraries/scrcpy/src/1_24/impl/defaults.ts index 34eceb97..44589814 100644 --- a/libraries/scrcpy/src/1_24/impl/defaults.ts +++ b/libraries/scrcpy/src/1_24/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - powerOn: true, - }) as const satisfies Required)(); +export const Defaults = { + ...PrevImpl.Defaults, + powerOn: true, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/1_24/options.ts b/libraries/scrcpy/src/1_24/options.ts index 83fa7218..948cf0bd 100644 --- a/libraries/scrcpy/src/1_24/options.ts +++ b/libraries/scrcpy/src/1_24/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -33,6 +32,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -44,7 +44,7 @@ export class ScrcpyOptions1_24 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -63,10 +63,12 @@ export class ScrcpyOptions1_24 constructor(init: Init) { this.value = { ...Defaults, ...init }; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -122,8 +124,9 @@ export class ScrcpyOptions1_24 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/1_25/impl/scroll-controller.ts b/libraries/scrcpy/src/1_25/impl/scroll-controller.ts index 01cc672c..3cd2b10f 100644 --- a/libraries/scrcpy/src/1_25/impl/scroll-controller.ts +++ b/libraries/scrcpy/src/1_25/impl/scroll-controller.ts @@ -3,7 +3,6 @@ import type { Field, StructInit } from "@yume-chan/struct"; import { field, struct, u16, u32, u8 } from "@yume-chan/struct"; import type { ScrcpyScrollController } from "../../base/index.js"; -import { ScrcpyControlMessageType } from "../../base/index.js"; import type { ScrcpyInjectScrollControlMessage } from "../../latest.js"; import { clamp } from "../../utils/index.js"; @@ -24,20 +23,20 @@ export const SignedFloat: Field = field( }, ); -export const InjectScrollControlMessage = /* #__PURE__ */ (() => - struct( - { - type: u8(ScrcpyControlMessageType.InjectScroll), - pointerX: u32, - pointerY: u32, - videoWidth: u16, - videoHeight: u16, - scrollX: SignedFloat, - scrollY: SignedFloat, - buttons: u32, - }, - { littleEndian: false }, - ))(); +export const InjectScrollControlMessage = struct( + { + // value of `type` can change between versions + type: u8, + pointerX: u32, + pointerY: u32, + videoWidth: u16, + videoHeight: u16, + scrollX: SignedFloat, + scrollY: SignedFloat, + buttons: u32, + }, + { littleEndian: false }, +); export type InjectScrollControlMessage = StructInit< typeof InjectScrollControlMessage diff --git a/libraries/scrcpy/src/1_25/options.ts b/libraries/scrcpy/src/1_25/options.ts index cec5b1b7..610c3dbc 100644 --- a/libraries/scrcpy/src/1_25/options.ts +++ b/libraries/scrcpy/src/1_25/options.ts @@ -2,7 +2,6 @@ import type { MaybePromiseLike } from "@yume-chan/async"; import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -33,6 +32,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -44,7 +44,7 @@ export class ScrcpyOptions1_25 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -63,10 +63,12 @@ export class ScrcpyOptions1_25 constructor(init: Init) { this.value = { ...Defaults, ...init }; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -122,8 +124,9 @@ export class ScrcpyOptions1_25 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_0/impl/defaults.ts b/libraries/scrcpy/src/2_0/impl/defaults.ts index 5c0653f2..770f8ea5 100644 --- a/libraries/scrcpy/src/2_0/impl/defaults.ts +++ b/libraries/scrcpy/src/2_0/impl/defaults.ts @@ -1,25 +1,30 @@ -import { omit } from "../../utils/index.js"; - import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...omit(PrevImpl.Defaults, "bitRate", "codecOptions", "encoderName"), - scid: undefined, +export const Defaults = { + ...{ + ...PrevImpl.Defaults, + // Remove obsolete values + // relies on the minifier to flatten the nested spread + bitRate: undefined, + codecOptions: undefined, + encoderName: undefined, + }, - videoCodec: "h264", - videoBitRate: 8000000, - videoCodecOptions: undefined, - videoEncoder: undefined, + scid: undefined, - audio: true, - audioCodec: "opus", - audioBitRate: 128000, - audioCodecOptions: undefined, - audioEncoder: undefined, + videoCodec: "h264", + videoBitRate: 8000000, + videoCodecOptions: undefined, + videoEncoder: undefined, - listEncoders: false, - listDisplays: false, - sendCodecMeta: true, - }) as const satisfies Required)(); + audio: true, + audioCodec: "opus", + audioBitRate: 128000, + audioCodecOptions: undefined, + audioEncoder: undefined, + + listEncoders: false, + listDisplays: false, + sendCodecMeta: true, +} as const satisfies Required; diff --git a/libraries/scrcpy/src/2_0/impl/inject-touch.ts b/libraries/scrcpy/src/2_0/impl/inject-touch.ts index 133ee692..6419e377 100644 --- a/libraries/scrcpy/src/2_0/impl/inject-touch.ts +++ b/libraries/scrcpy/src/2_0/impl/inject-touch.ts @@ -2,27 +2,26 @@ import type { StructInit } from "@yume-chan/struct"; import { struct, u16, u32, u64, u8 } from "@yume-chan/struct"; import type { AndroidMotionEventAction } from "../../android/motion-event.js"; -import { ScrcpyControlMessageType } from "../../base/control-message-type.js"; import type { ScrcpyInjectTouchControlMessage } from "../../latest.js"; import { PrevImpl } from "./prev.js"; -export const InjectTouchControlMessage = /* #__PURE__ */ (() => - struct( - { - type: u8(ScrcpyControlMessageType.InjectTouch), - action: u8(), - pointerId: u64, - pointerX: u32, - pointerY: u32, - videoWidth: u16, - videoHeight: u16, - pressure: PrevImpl.UnsignedFloat, - actionButton: u32, - buttons: u32, - }, - { littleEndian: false }, - ))(); +export const InjectTouchControlMessage = struct( + { + // value of `type` can change between versions + type: u8, + action: u8(), + pointerId: u64, + pointerX: u32, + pointerY: u32, + videoWidth: u16, + videoHeight: u16, + pressure: PrevImpl.UnsignedFloat, + actionButton: u32, + buttons: u32, + }, + { littleEndian: false }, +); export type InjectTouchControlMessage = StructInit< typeof InjectTouchControlMessage diff --git a/libraries/scrcpy/src/2_0/options.ts b/libraries/scrcpy/src/2_0/options.ts index 654fedf9..c33bce82 100644 --- a/libraries/scrcpy/src/2_0/options.ts +++ b/libraries/scrcpy/src/2_0/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -34,6 +33,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -45,7 +45,7 @@ export class ScrcpyOptions2_0 readonly value: Required; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -64,10 +64,12 @@ export class ScrcpyOptions2_0 constructor(init: Init) { this.value = { ...Defaults, ...init }; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -129,8 +131,9 @@ export class ScrcpyOptions2_0 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_1/impl/defaults.ts b/libraries/scrcpy/src/2_1/impl/defaults.ts index 99b0ed27..c3aac21b 100644 --- a/libraries/scrcpy/src/2_1/impl/defaults.ts +++ b/libraries/scrcpy/src/2_1/impl/defaults.ts @@ -1,9 +1,8 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - video: true, - audioSource: "output", - }) as const satisfies Required>)(); +export const Defaults = { + ...PrevImpl.Defaults, + video: true, + audioSource: "output", +} as const satisfies Required>; diff --git a/libraries/scrcpy/src/2_1/options.ts b/libraries/scrcpy/src/2_1/options.ts index 55223707..75207779 100644 --- a/libraries/scrcpy/src/2_1/options.ts +++ b/libraries/scrcpy/src/2_1/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -34,6 +33,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -45,7 +45,7 @@ export class ScrcpyOptions2_1 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -64,10 +64,12 @@ export class ScrcpyOptions2_1 constructor(init: Init) { this.value = { ...Defaults, ...init } as never; - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -129,8 +131,9 @@ export class ScrcpyOptions2_1 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_1_1.ts b/libraries/scrcpy/src/2_1_1.ts index a2c3f33a..7dbf968c 100644 --- a/libraries/scrcpy/src/2_1_1.ts +++ b/libraries/scrcpy/src/2_1_1.ts @@ -1,14 +1 @@ -import { ScrcpyOptions2_1 } from "./2_1/index.js"; - -export class ScrcpyOptions2_1_1< - TVideo extends boolean, -> extends ScrcpyOptions2_1 { - constructor(init: ScrcpyOptions2_1.Init) { - super(init); - } -} - -export namespace ScrcpyOptions2_1_1 { - export type Init = - ScrcpyOptions2_1.Init; -} +export { ScrcpyOptions2_1 as ScrcpyOptions2_1_1 } from "./2_1/index.js"; diff --git a/libraries/scrcpy/src/2_2/impl/defaults.ts b/libraries/scrcpy/src/2_2/impl/defaults.ts index 3bac3c9a..92fb0de4 100644 --- a/libraries/scrcpy/src/2_2/impl/defaults.ts +++ b/libraries/scrcpy/src/2_2/impl/defaults.ts @@ -1,17 +1,16 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - videoSource: "display", - displayId: 0, - cameraId: undefined, - cameraSize: undefined, - cameraFacing: undefined, - cameraAr: undefined, - cameraFps: undefined, - cameraHighSpeed: false, - listCameras: false, - listCameraSizes: false, - }) as const satisfies Required>)(); +export const Defaults = { + ...PrevImpl.Defaults, + videoSource: "display", + displayId: 0, + cameraId: undefined, + cameraSize: undefined, + cameraFacing: undefined, + cameraAr: undefined, + cameraFps: undefined, + cameraHighSpeed: false, + listCameras: false, + listCameraSizes: false, +} as const satisfies Required>; diff --git a/libraries/scrcpy/src/2_2/options.ts b/libraries/scrcpy/src/2_2/options.ts index bee1f75c..395bf382 100644 --- a/libraries/scrcpy/src/2_2/options.ts +++ b/libraries/scrcpy/src/2_2/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -34,6 +33,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -45,7 +45,7 @@ export class ScrcpyOptions2_2 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -68,10 +68,12 @@ export class ScrcpyOptions2_2 this.value.control = false; } - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -133,8 +135,9 @@ export class ScrcpyOptions2_2 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_3/options.ts b/libraries/scrcpy/src/2_3/options.ts index d523f0b3..09462b2b 100644 --- a/libraries/scrcpy/src/2_3/options.ts +++ b/libraries/scrcpy/src/2_3/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -34,6 +33,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, setListDisplays, setListEncoders, } from "./impl/index.js"; @@ -45,7 +45,7 @@ export class ScrcpyOptions2_3 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -68,10 +68,12 @@ export class ScrcpyOptions2_3 this.value.control = false; } - if (this.value.control && this.value.clipboardAutosync) { - this.#clipboard = this.#deviceMessageParsers.add( - new ClipboardStream(), - ); + if (this.value.control) { + if (this.value.clipboardAutosync) { + this.#clipboard = this.#deviceMessageParsers.add( + new ClipboardStream(), + ); + } this.#ackClipboardHandler = this.#deviceMessageParsers.add( new AckClipboardHandler(), @@ -133,8 +135,9 @@ export class ScrcpyOptions2_3 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_3_1.ts b/libraries/scrcpy/src/2_3_1.ts index af9cd3df..aff4e253 100644 --- a/libraries/scrcpy/src/2_3_1.ts +++ b/libraries/scrcpy/src/2_3_1.ts @@ -1,14 +1 @@ -import { ScrcpyOptions2_3 } from "./2_3/index.js"; - -export class ScrcpyOptions2_3_1< - TVideo extends boolean, -> extends ScrcpyOptions2_3 { - constructor(init: ScrcpyOptions2_3.Init) { - super(init); - } -} - -export namespace ScrcpyOptions2_3_1 { - export type Init = - ScrcpyOptions2_3.Init; -} +export { ScrcpyOptions2_3 as ScrcpyOptions2_3_1 } from "./2_3/index.js"; diff --git a/libraries/scrcpy/src/2_4/impl/control-message-types.ts b/libraries/scrcpy/src/2_4/impl/control-message-types.ts index 34dd33d0..28c870cb 100644 --- a/libraries/scrcpy/src/2_4/impl/control-message-types.ts +++ b/libraries/scrcpy/src/2_4/impl/control-message-types.ts @@ -1,11 +1,20 @@ +import type { ScrcpyControlMessageTypeMap } from "../../base/index.js"; import { ScrcpyControlMessageType } from "../../base/index.js"; -import { PrevImpl } from "./prev.js"; - -export const ControlMessageTypes: readonly ScrcpyControlMessageType[] = - /* #__PURE__ */ (() => [ - ...PrevImpl.ControlMessageTypes, - ScrcpyControlMessageType.UHidCreate, - ScrcpyControlMessageType.UHidInput, - ScrcpyControlMessageType.OpenHardKeyboardSettings, - ])(); +export const ControlMessageTypes = { + [ScrcpyControlMessageType.InjectKeyCode]: 0, + [ScrcpyControlMessageType.InjectText]: 1, + [ScrcpyControlMessageType.InjectTouch]: 2, + [ScrcpyControlMessageType.InjectScroll]: 3, + [ScrcpyControlMessageType.BackOrScreenOn]: 4, + [ScrcpyControlMessageType.ExpandNotificationPanel]: 5, + [ScrcpyControlMessageType.ExpandSettingPanel]: 6, + [ScrcpyControlMessageType.CollapseNotificationPanel]: 7, + [ScrcpyControlMessageType.GetClipboard]: 8, + [ScrcpyControlMessageType.SetClipboard]: 9, + [ScrcpyControlMessageType.SetDisplayPower]: 10, + [ScrcpyControlMessageType.RotateDevice]: 11, + [ScrcpyControlMessageType.UHidCreate]: 12, + [ScrcpyControlMessageType.UHidInput]: 13, + [ScrcpyControlMessageType.OpenHardKeyboardSettings]: 14, +} as const satisfies ScrcpyControlMessageTypeMap; diff --git a/libraries/scrcpy/src/2_4/impl/serialize-uhid-create.ts b/libraries/scrcpy/src/2_4/impl/serialize-uhid-create.ts index 16e0f9f1..4f45eeab 100644 --- a/libraries/scrcpy/src/2_4/impl/serialize-uhid-create.ts +++ b/libraries/scrcpy/src/2_4/impl/serialize-uhid-create.ts @@ -5,6 +5,7 @@ import type { ScrcpyUHidCreateControlMessage } from "../../latest.js"; export const UHidCreateControlMessage = struct( { + // value of `type` can change between versions type: u8, id: u16, data: buffer(u16), diff --git a/libraries/scrcpy/src/2_4/options.ts b/libraries/scrcpy/src/2_4/options.ts index d9bb7eec..08c7306d 100644 --- a/libraries/scrcpy/src/2_4/options.ts +++ b/libraries/scrcpy/src/2_4/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions2_4 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -84,12 +84,12 @@ export class ScrcpyOptions2_4 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -150,8 +150,9 @@ export class ScrcpyOptions2_4 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_5.ts b/libraries/scrcpy/src/2_5.ts index eabb0270..93b1b7cf 100644 --- a/libraries/scrcpy/src/2_5.ts +++ b/libraries/scrcpy/src/2_5.ts @@ -1,14 +1 @@ -import { ScrcpyOptions2_4 } from "./2_4/index.js"; - -export class ScrcpyOptions2_5< - TVideo extends boolean, -> extends ScrcpyOptions2_4 { - constructor(init: ScrcpyOptions2_4.Init) { - super(init); - } -} - -export namespace ScrcpyOptions2_5 { - export type Init = - ScrcpyOptions2_4.Init; -} +export { ScrcpyOptions2_4 as ScrcpyOptions2_5 } from "./2_4/index.js"; diff --git a/libraries/scrcpy/src/2_6/impl/defaults.ts b/libraries/scrcpy/src/2_6/impl/defaults.ts index 9b710a5d..35b25cf4 100644 --- a/libraries/scrcpy/src/2_6/impl/defaults.ts +++ b/libraries/scrcpy/src/2_6/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - audioDup: false, - }) as const satisfies Required>)(); +export const Defaults = { + ...PrevImpl.Defaults, + audioDup: false, +} as const satisfies Required>; diff --git a/libraries/scrcpy/src/2_6/options.ts b/libraries/scrcpy/src/2_6/options.ts index 778a901e..ee32bbcd 100644 --- a/libraries/scrcpy/src/2_6/options.ts +++ b/libraries/scrcpy/src/2_6/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions2_6 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -88,12 +88,12 @@ export class ScrcpyOptions2_6 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -154,8 +154,9 @@ export class ScrcpyOptions2_6 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/2_6_1.ts b/libraries/scrcpy/src/2_6_1.ts index 483731cf..984035cb 100644 --- a/libraries/scrcpy/src/2_6_1.ts +++ b/libraries/scrcpy/src/2_6_1.ts @@ -1,14 +1 @@ -import { ScrcpyOptions2_6 } from "./2_6/index.js"; - -export class ScrcpyOptions2_6_1< - TVideo extends boolean, -> extends ScrcpyOptions2_6 { - constructor(init: ScrcpyOptions2_6.Init) { - super(init); - } -} - -export namespace ScrcpyOptions2_6_1 { - export type Init = - ScrcpyOptions2_6.Init; -} +export { ScrcpyOptions2_6 as ScrcpyOptions2_6_1 } from "./2_6/index.js"; diff --git a/libraries/scrcpy/src/2_7/impl/control-message-types.ts b/libraries/scrcpy/src/2_7/impl/control-message-types.ts index cf01ddb7..d5bc48ec 100644 --- a/libraries/scrcpy/src/2_7/impl/control-message-types.ts +++ b/libraries/scrcpy/src/2_7/impl/control-message-types.ts @@ -1,10 +1,21 @@ +import type { ScrcpyControlMessageTypeMap } from "../../base/index.js"; import { ScrcpyControlMessageType } from "../../base/index.js"; -import { PrevImpl } from "./prev.js"; - -export const ControlMessageTypes: readonly ScrcpyControlMessageType[] = - /* #__PURE__ */ (() => { - const result = PrevImpl.ControlMessageTypes.slice(); - result.splice(14, 0, ScrcpyControlMessageType.UHidDestroy); - return result; - })(); +export const ControlMessageTypes = { + [ScrcpyControlMessageType.InjectKeyCode]: 0, + [ScrcpyControlMessageType.InjectText]: 1, + [ScrcpyControlMessageType.InjectTouch]: 2, + [ScrcpyControlMessageType.InjectScroll]: 3, + [ScrcpyControlMessageType.BackOrScreenOn]: 4, + [ScrcpyControlMessageType.ExpandNotificationPanel]: 5, + [ScrcpyControlMessageType.ExpandSettingPanel]: 6, + [ScrcpyControlMessageType.CollapseNotificationPanel]: 7, + [ScrcpyControlMessageType.GetClipboard]: 8, + [ScrcpyControlMessageType.SetClipboard]: 9, + [ScrcpyControlMessageType.SetDisplayPower]: 10, + [ScrcpyControlMessageType.RotateDevice]: 11, + [ScrcpyControlMessageType.UHidCreate]: 12, + [ScrcpyControlMessageType.UHidInput]: 13, + [ScrcpyControlMessageType.UHidDestroy]: 14, + [ScrcpyControlMessageType.OpenHardKeyboardSettings]: 15, +} as const satisfies ScrcpyControlMessageTypeMap; diff --git a/libraries/scrcpy/src/2_7/impl/serialize-uhid-create.ts b/libraries/scrcpy/src/2_7/impl/serialize-uhid-create.ts index b3be3ae0..884a9be8 100644 --- a/libraries/scrcpy/src/2_7/impl/serialize-uhid-create.ts +++ b/libraries/scrcpy/src/2_7/impl/serialize-uhid-create.ts @@ -5,6 +5,7 @@ import type { ScrcpyUHidCreateControlMessage } from "../../latest.js"; export const UHidCreateControlMessage = struct( { + // value of `type` can change between versions type: u8, id: u16, name: string(u8), diff --git a/libraries/scrcpy/src/2_7/options.ts b/libraries/scrcpy/src/2_7/options.ts index 498858b6..b63c1170 100644 --- a/libraries/scrcpy/src/2_7/options.ts +++ b/libraries/scrcpy/src/2_7/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions2_7 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -88,12 +88,12 @@ export class ScrcpyOptions2_7 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -154,8 +154,9 @@ export class ScrcpyOptions2_7 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/3_0/impl/control-message-types.ts b/libraries/scrcpy/src/3_0/impl/control-message-types.ts index 6252fb79..ede9de4a 100644 --- a/libraries/scrcpy/src/3_0/impl/control-message-types.ts +++ b/libraries/scrcpy/src/3_0/impl/control-message-types.ts @@ -1,10 +1,23 @@ +import type { ScrcpyControlMessageTypeMap } from "../../base/index.js"; import { ScrcpyControlMessageType } from "../../base/index.js"; -import { PrevImpl } from "./prev.js"; - -export const ControlMessageTypes: readonly ScrcpyControlMessageType[] = - /* #__PURE__ */ (() => [ - ...PrevImpl.ControlMessageTypes, - ScrcpyControlMessageType.StartApp, - ScrcpyControlMessageType.ResetVideo, - ])(); +export const ControlMessageTypes = { + [ScrcpyControlMessageType.InjectKeyCode]: 0, + [ScrcpyControlMessageType.InjectText]: 1, + [ScrcpyControlMessageType.InjectTouch]: 2, + [ScrcpyControlMessageType.InjectScroll]: 3, + [ScrcpyControlMessageType.BackOrScreenOn]: 4, + [ScrcpyControlMessageType.ExpandNotificationPanel]: 5, + [ScrcpyControlMessageType.ExpandSettingPanel]: 6, + [ScrcpyControlMessageType.CollapseNotificationPanel]: 7, + [ScrcpyControlMessageType.GetClipboard]: 8, + [ScrcpyControlMessageType.SetClipboard]: 9, + [ScrcpyControlMessageType.SetDisplayPower]: 10, + [ScrcpyControlMessageType.RotateDevice]: 11, + [ScrcpyControlMessageType.UHidCreate]: 12, + [ScrcpyControlMessageType.UHidInput]: 13, + [ScrcpyControlMessageType.UHidDestroy]: 14, + [ScrcpyControlMessageType.OpenHardKeyboardSettings]: 15, + [ScrcpyControlMessageType.StartApp]: 16, + [ScrcpyControlMessageType.ResetVideo]: 17, +} as const satisfies ScrcpyControlMessageTypeMap; diff --git a/libraries/scrcpy/src/3_0/impl/defaults.ts b/libraries/scrcpy/src/3_0/impl/defaults.ts index 58faa2b7..5008b2ed 100644 --- a/libraries/scrcpy/src/3_0/impl/defaults.ts +++ b/libraries/scrcpy/src/3_0/impl/defaults.ts @@ -1,15 +1,18 @@ -import { omit } from "../../utils/index.js"; - import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...omit(PrevImpl.Defaults, "lockVideoOrientation"), - captureOrientation: undefined, - angle: 0, - screenOffTimeout: undefined, - listApps: false, - newDisplay: undefined, - vdSystemDecorations: true, - }) as const satisfies Required>)(); +export const Defaults = { + ...{ + ...PrevImpl.Defaults, + // Remove obsolete values + // relies on the minifier to flatten the nested spread + lockVideoOrientation: undefined, + }, + + captureOrientation: undefined, + angle: 0, + screenOffTimeout: undefined, + listApps: false, + newDisplay: undefined, + vdSystemDecorations: true, +} as const satisfies Required>; diff --git a/libraries/scrcpy/src/3_0/options.ts b/libraries/scrcpy/src/3_0/options.ts index 00be08b5..a5d1e1ee 100644 --- a/libraries/scrcpy/src/3_0/options.ts +++ b/libraries/scrcpy/src/3_0/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions3_0 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -88,12 +88,12 @@ export class ScrcpyOptions3_0 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -154,8 +154,9 @@ export class ScrcpyOptions3_0 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/3_0_1.ts b/libraries/scrcpy/src/3_0_1.ts index e6dee795..27c3e0e7 100644 --- a/libraries/scrcpy/src/3_0_1.ts +++ b/libraries/scrcpy/src/3_0_1.ts @@ -1,14 +1 @@ -import { ScrcpyOptions3_0 } from "./3_0/index.js"; - -export class ScrcpyOptions3_0_1< - TVideo extends boolean, -> extends ScrcpyOptions3_0 { - constructor(init: ScrcpyOptions3_0.Init) { - super(init); - } -} - -export namespace ScrcpyOptions3_0_1 { - export type Init = - ScrcpyOptions3_0.Init; -} +export { ScrcpyOptions3_0 as ScrcpyOptions3_0_1 } from "./3_0/index.js"; diff --git a/libraries/scrcpy/src/3_0_2.ts b/libraries/scrcpy/src/3_0_2.ts index 5443a75b..386bbedd 100644 --- a/libraries/scrcpy/src/3_0_2.ts +++ b/libraries/scrcpy/src/3_0_2.ts @@ -1,14 +1 @@ -import { ScrcpyOptions3_0 } from "./3_0/index.js"; - -export class ScrcpyOptions3_0_2< - TVideo extends boolean, -> extends ScrcpyOptions3_0 { - constructor(init: ScrcpyOptions3_0.Init) { - super(init); - } -} - -export namespace ScrcpyOptions3_0_2 { - export type Init = - ScrcpyOptions3_0.Init; -} +export { ScrcpyOptions3_0 as ScrcpyOptions3_0_2 } from "./3_0/index.js"; diff --git a/libraries/scrcpy/src/3_1/impl/defaults.ts b/libraries/scrcpy/src/3_1/impl/defaults.ts index 2882aae0..102562b3 100644 --- a/libraries/scrcpy/src/3_1/impl/defaults.ts +++ b/libraries/scrcpy/src/3_1/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - vdDestroyContent: false, - }) as const satisfies Required>)(); +export const Defaults = { + ...PrevImpl.Defaults, + vdDestroyContent: false, +} as const satisfies Required>; diff --git a/libraries/scrcpy/src/3_1/impl/serialize-uhid-create.ts b/libraries/scrcpy/src/3_1/impl/serialize-uhid-create.ts index 85013408..aee63ab8 100644 --- a/libraries/scrcpy/src/3_1/impl/serialize-uhid-create.ts +++ b/libraries/scrcpy/src/3_1/impl/serialize-uhid-create.ts @@ -5,6 +5,7 @@ import type { ScrcpyUHidCreateControlMessage } from "../../latest.js"; export const UHidCreateControlMessage = struct( { + // value of `type` can change between versions type: u8, id: u16, vendorId: u16, diff --git a/libraries/scrcpy/src/3_1/options.ts b/libraries/scrcpy/src/3_1/options.ts index cfe97c80..7169cc10 100644 --- a/libraries/scrcpy/src/3_1/options.ts +++ b/libraries/scrcpy/src/3_1/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions3_1 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -88,12 +88,12 @@ export class ScrcpyOptions3_1 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -154,8 +154,9 @@ export class ScrcpyOptions3_1 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/3_2/impl/defaults.ts b/libraries/scrcpy/src/3_2/impl/defaults.ts index 73906a29..1e2e7911 100644 --- a/libraries/scrcpy/src/3_2/impl/defaults.ts +++ b/libraries/scrcpy/src/3_2/impl/defaults.ts @@ -1,8 +1,7 @@ import type { Init } from "./init.js"; import { PrevImpl } from "./prev.js"; -export const Defaults = /* #__PURE__ */ (() => - ({ - ...PrevImpl.Defaults, - displayImePolicy: undefined, - }) as const satisfies Required>)(); +export const Defaults = { + ...PrevImpl.Defaults, + displayImePolicy: undefined, +} as const satisfies Required>; diff --git a/libraries/scrcpy/src/3_2/options.ts b/libraries/scrcpy/src/3_2/options.ts index 1b15dd30..7bd3cd82 100644 --- a/libraries/scrcpy/src/3_2/options.ts +++ b/libraries/scrcpy/src/3_2/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions3_2 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -88,12 +88,12 @@ export class ScrcpyOptions3_2 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -154,8 +154,9 @@ export class ScrcpyOptions3_2 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/3_3.ts b/libraries/scrcpy/src/3_3.ts index f59138a9..8d414bbf 100644 --- a/libraries/scrcpy/src/3_3.ts +++ b/libraries/scrcpy/src/3_3.ts @@ -1,14 +1 @@ -import { ScrcpyOptions3_2 } from "./3_2/index.js"; - -export class ScrcpyOptions3_3< - TVideo extends boolean, -> extends ScrcpyOptions3_2 { - constructor(init: ScrcpyOptions3_2.Init) { - super(init); - } -} - -export namespace ScrcpyOptions3_3 { - export type Init = - ScrcpyOptions3_2.Init; -} +export { ScrcpyOptions3_2 as ScrcpyOptions3_3 } from "./3_2/index.js"; diff --git a/libraries/scrcpy/src/3_3_1/options.ts b/libraries/scrcpy/src/3_3_1/options.ts index 184e7ab6..986c585f 100644 --- a/libraries/scrcpy/src/3_3_1/options.ts +++ b/libraries/scrcpy/src/3_3_1/options.ts @@ -3,7 +3,6 @@ import type { ReadableStream, TransformStream } from "@yume-chan/stream-extra"; import type { ScrcpyAudioStreamMetadata, - ScrcpyControlMessageType, ScrcpyDisplay, ScrcpyEncoder, ScrcpyMediaStreamPacket, @@ -36,6 +35,7 @@ import { serialize, serializeBackOrScreenOnControlMessage, serializeInjectTouchControlMessage, + serializeSetClipboardControlMessage, serializeUHidCreateControlMessage, setListDisplays, setListEncoders, @@ -49,7 +49,7 @@ export class ScrcpyOptions3_3_1 readonly value: Required>; - get controlMessageTypes(): readonly ScrcpyControlMessageType[] { + get controlMessageTypes(): typeof ControlMessageTypes { return ControlMessageTypes; } @@ -88,12 +88,12 @@ export class ScrcpyOptions3_3_1 this.#clipboard = this.#deviceMessageParsers.add( new ClipboardStream(), ); - - this.#ackClipboardHandler = this.#deviceMessageParsers.add( - new AckClipboardHandler(), - ); } + this.#ackClipboardHandler = this.#deviceMessageParsers.add( + new AckClipboardHandler(), + ); + this.#uHidOutput = this.#deviceMessageParsers.add( new UHidOutputStream(), ); @@ -154,8 +154,9 @@ export class ScrcpyOptions3_3_1 serializeSetClipboardControlMessage( message: ScrcpySetClipboardControlMessage, ): Uint8Array | [Uint8Array, Promise] { - return this.#ackClipboardHandler!.serializeSetClipboardControlMessage( + return serializeSetClipboardControlMessage( message, + this.#ackClipboardHandler, ); } diff --git a/libraries/scrcpy/src/3_3_2.ts b/libraries/scrcpy/src/3_3_2.ts index 0897b9c0..58a886e7 100644 --- a/libraries/scrcpy/src/3_3_2.ts +++ b/libraries/scrcpy/src/3_3_2.ts @@ -1,14 +1 @@ -import { ScrcpyOptions3_3_1 } from "./3_3_1/index.js"; - -export class ScrcpyOptions3_3_2< - TVideo extends boolean, -> extends ScrcpyOptions3_3_1 { - constructor(init: ScrcpyOptions3_3_1.Init) { - super(init); - } -} - -export namespace ScrcpyOptions3_3_2 { - export type Init = - ScrcpyOptions3_3_1.Init; -} +export { ScrcpyOptions3_3_1 as ScrcpyOptions3_3_2 } from "./3_3_1/index.js"; diff --git a/libraries/scrcpy/src/android/key-code-value.ts b/libraries/scrcpy/src/android/key-code-value.ts new file mode 100644 index 00000000..f4dc2c56 --- /dev/null +++ b/libraries/scrcpy/src/android/key-code-value.ts @@ -0,0 +1,194 @@ +// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/KeyEvent.java;l=97;drc=95c1165bb895dd844e1793460710f7163dd330a3 +// Android key code to Chrome key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/keyboard_code_conversion_android.cc +// Chrome key code to DOM key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_code_data.inc +// Some keys are not mapped to `KeyboardEvent.code`, only to `KeyboardEvent.key`: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_key_data.inc + +export const AndroidHome = 3; +export const AndroidBack = 4; +export const AndroidCall = 5; +export const AndroidEndCall = 6; + +export const Digit0 = 7; +export const Digit1 = 8; +export const Digit2 = 9; +export const Digit3 = 10; +export const Digit4 = 11; +export const Digit5 = 12; +export const Digit6 = 13; +export const Digit7 = 14; +export const Digit8 = 15; +export const Digit9 = 16; + +/** + * '*' key. + */ +export const Star = 17; // Name not verified +/** + * '#' key. + */ +export const Pound = 18; // Name not verified + +/** + * Directional Pad Up key. + */ +export const ArrowUp = 19; +/** + * Directional Pad Down key. + */ +export const ArrowDown = 20; +/** + * Directional Pad Left key. + */ +export const ArrowLeft = 21; +/** + * Directional Pad Right key. + */ +export const ArrowRight = 22; +/** + * Directional Pad Center key. + */ +export const AndroidDPadCenter = 23; + +export const VolumeUp = 24; // Name not verified +export const VolumeDown = 25; // Name not verified +export const Power = 26; // Name not verified +export const AndroidCamera = 27; +export const Clear = 28; // Name not verified + +export const KeyA = 29; +export const KeyB = 30; +export const KeyC = 31; +export const KeyD = 32; +export const KeyE = 33; +export const KeyF = 34; +export const KeyG = 35; +export const KeyH = 36; +export const KeyI = 37; +export const KeyJ = 38; +export const KeyK = 39; +export const KeyL = 40; +export const KeyM = 41; +export const KeyN = 42; +export const KeyO = 43; +export const KeyP = 44; +export const KeyQ = 45; +export const KeyR = 46; +export const KeyS = 47; +export const KeyT = 48; +export const KeyU = 49; +export const KeyV = 50; +export const KeyW = 51; +export const KeyX = 52; +export const KeyY = 53; +export const KeyZ = 54; +export const Comma = 55; +export const Period = 56; +export const AltLeft = 57; +export const AltRight = 58; +export const ShiftLeft = 59; +export const ShiftRight = 60; +export const Tab = 61; +export const Space = 62; +export const AndroidSymbol = 63; +export const AndroidExplorer = 64; +export const AndroidEnvelope = 65; +export const Enter = 66; +export const Backspace = 67; +export const Backquote = 68; +export const Minus = 69; +export const Equal = 70; +export const BracketLeft = 71; +export const BracketRight = 72; +export const Backslash = 73; +export const Semicolon = 74; +export const Quote = 75; +export const Slash = 76; +export const At = 77; // Name not verified + +/** + * Number modifier key. + * + * Used to enter numeric symbols. + * This key is not Num Lock; it is more like {@link AltLeft} and is + * interpreted as an ALT key by `android.text.method.MetaKeyKeyListener`. + */ +export const AndroidNum = 78; +/** + * Headset Hook key. + * + * Used to hang up calls and stop media. + */ +export const AndroidHeadsetHook = 79; +/** + * Camera Focus key. + * + * Used to focus the camera. + */ +export const AndroidFocus = 80; + +export const Plus = 81; // Name not verified +export const ContextMenu = 82; +export const AndroidNotification = 83; +export const AndroidSearch = 84; + +export const PageUp = 92; +export const PageDown = 93; + +export const Escape = 111; +export const Delete = 112; +export const ControlLeft = 113; +export const ControlRight = 114; +export const CapsLock = 115; +export const ScrollLock = 116; +export const MetaLeft = 117; +export const MetaRight = 118; +export const AndroidFunction = 119; +export const PrintScreen = 120; +export const Pause = 121; + +export const Home = 122; +export const End = 123; +export const Insert = 124; +export const AndroidForward = 125; + +export const F1 = 131; +export const F2 = 132; +export const F3 = 133; +export const F4 = 134; +export const F5 = 135; +export const F6 = 136; +export const F7 = 137; +export const F8 = 138; +export const F9 = 139; +export const F10 = 140; +export const F11 = 141; +export const F12 = 142; + +export const NumLock = 143; +export const Numpad0 = 144; +export const Numpad1 = 145; +export const Numpad2 = 146; +export const Numpad3 = 147; +export const Numpad4 = 148; +export const Numpad5 = 149; +export const Numpad6 = 150; +export const Numpad7 = 151; +export const Numpad8 = 152; +export const Numpad9 = 153; +export const NumpadDivide = 154; +export const NumpadMultiply = 155; +export const NumpadSubtract = 156; +export const NumpadAdd = 157; +export const NumpadDecimal = 158; +export const NumpadComma = 159; // Name not verified +export const NumpadEnter = 160; +export const NumpadEquals = 161; // Name not verified +export const NumpadLeftParen = 162; // Name not verified +export const NumpadRightParen = 163; // Name not verified + +export const VolumeMute = 164; // Name not verified +export const AndroidAppSwitch = 187; // Name not verified + +export const AndroidCut = 277; +export const AndroidCopy = 278; +export const AndroidPaste = 279; diff --git a/libraries/scrcpy/src/android/key-event.ts b/libraries/scrcpy/src/android/key-event.ts index 863ff7d6..8d9dbb2b 100644 --- a/libraries/scrcpy/src/android/key-event.ts +++ b/libraries/scrcpy/src/android/key-event.ts @@ -1,3 +1,5 @@ +import * as AndroidKeyCode from "./key-code-value.js"; + export const AndroidKeyEventAction = { Down: 0, Up: 1, @@ -29,189 +31,10 @@ export const AndroidKeyEventMeta = { export type AndroidKeyEventMeta = (typeof AndroidKeyEventMeta)[keyof typeof AndroidKeyEventMeta]; -// https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/view/KeyEvent.java;l=97;drc=95c1165bb895dd844e1793460710f7163dd330a3 -// Android key code to Chrome key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/keyboard_code_conversion_android.cc -// Chrome key code to DOM key code: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_code_data.inc -// Some keys are not mapped to `KeyboardEvent.code`, only to `KeyboardEvent.key`: https://source.chromium.org/chromium/chromium/src/+/main:ui/events/keycodes/dom/dom_key_data.inc -export const AndroidKeyCode = { - AndroidHome: 3, - AndroidBack: 4, - AndroidCall: 5, - AndroidEndCall: 6, +// biome-ignore lint/suspicious/noRedeclare: TypeScript declaration merging for enum-like object +type AndroidKeyCode = (typeof AndroidKeyCode)[keyof typeof AndroidKeyCode]; - Digit0: 7, - Digit1: 8, - Digit2: 9, - Digit3: 10, - Digit4: 11, - Digit5: 12, - Digit6: 13, - Digit7: 14, - Digit8: 15, - Digit9: 16, - /** - * '*' key. - */ - Star: 17, // Name not verified - /** - * '#' key. - */ - Pound: 18, // Name not verified - - /** - * Directional Pad Up key. - */ - ArrowUp: 19, - /** - * Directional Pad Down key. - */ - ArrowDown: 20, - /** - * Directional Pad Left key. - */ - ArrowLeft: 21, - /** - * Directional Pad Right key. - */ - ArrowRight: 22, - /** - * Directional Pad Center key. - */ - AndroidDPadCenter: 23, - - VolumeUp: 24, // Name not verified - VolumeDown: 25, // Name not verified - Power: 26, // Name not verified - AndroidCamera: 27, - Clear: 28, // Name not verified - - KeyA: 29, - KeyB: 30, - KeyC: 31, - KeyD: 32, - KeyE: 33, - KeyF: 34, - KeyG: 35, - KeyH: 36, - KeyI: 37, - KeyJ: 38, - KeyK: 39, - KeyL: 40, - KeyM: 41, - KeyN: 42, - KeyO: 43, - KeyP: 44, - KeyQ: 45, - KeyR: 46, - KeyS: 47, - KeyT: 48, - KeyU: 49, - KeyV: 50, - KeyW: 51, - KeyX: 52, - KeyY: 53, - KeyZ: 54, - Comma: 55, - Period: 56, - AltLeft: 57, - AltRight: 58, - ShiftLeft: 59, - ShiftRight: 60, - Tab: 61, - Space: 62, - AndroidSymbol: 63, - AndroidExplorer: 64, - AndroidEnvelope: 65, - Enter: 66, - Backspace: 67, - Backquote: 68, - Minus: 69, - Equal: 70, - BracketLeft: 71, - BracketRight: 72, - Backslash: 73, - Semicolon: 74, - Quote: 75, - Slash: 76, - At: 77, // Name not verified - - AndroidNum: 78, - AndroidHeadsetHook: 79, - /** - * Camera Focus key。 - */ - AndroidFocus: 80, - - Plus: 81, // Name not verified - ContextMenu: 82, - AndroidNotification: 83, - AndroidSearch: 84, - - PageUp: 92, - PageDown: 93, - - Escape: 111, - Delete: 112, - ControlLeft: 113, - ControlRight: 114, - CapsLock: 115, - ScrollLock: 116, - MetaLeft: 117, - MetaRight: 118, - AndroidFunction: 119, - PrintScreen: 120, - Pause: 121, - - Home: 122, - End: 123, - Insert: 124, - AndroidForward: 125, - - F1: 131, - F2: 132, - F3: 133, - F4: 134, - F5: 135, - F6: 136, - F7: 137, - F8: 138, - F9: 139, - F10: 140, - F11: 141, - F12: 142, - - NumLock: 143, - Numpad0: 144, - Numpad1: 145, - Numpad2: 146, - Numpad3: 147, - Numpad4: 148, - Numpad5: 149, - Numpad6: 150, - Numpad7: 151, - Numpad8: 152, - Numpad9: 153, - NumpadDivide: 154, - NumpadMultiply: 155, - NumpadSubtract: 156, - NumpadAdd: 157, - NumpadDecimal: 158, - NumpadComma: 159, // Name not verified - NumpadEnter: 160, - NumpadEquals: 161, // Name not verified - NumpadLeftParen: 162, // Name not verified - NumpadRightParen: 163, // Name not verified - - VolumeMute: 164, // Name not verified - AndroidAppSwitch: 187, // Name not verified - - AndroidCut: 277, - AndroidCopy: 278, - AndroidPaste: 279, -} as const; - -export type AndroidKeyCode = - (typeof AndroidKeyCode)[keyof typeof AndroidKeyCode]; +export { AndroidKeyCode }; export const AndroidKeyNames = /* #__PURE__ */ (() => Object.fromEntries( diff --git a/libraries/scrcpy/src/base/control-message-type-value.ts b/libraries/scrcpy/src/base/control-message-type-value.ts new file mode 100644 index 00000000..60ba2299 --- /dev/null +++ b/libraries/scrcpy/src/base/control-message-type-value.ts @@ -0,0 +1,18 @@ +export const InjectKeyCode = 0; +export const InjectText = 1; +export const InjectTouch = 2; +export const InjectScroll = 3; +export const BackOrScreenOn = 4; +export const ExpandNotificationPanel = 5; +export const ExpandSettingPanel = 6; +export const CollapseNotificationPanel = 7; +export const GetClipboard = 8; +export const SetClipboard = 9; +export const SetDisplayPower = 10; +export const RotateDevice = 11; +export const UHidCreate = 12; +export const UHidInput = 13; +export const UHidDestroy = 14; +export const OpenHardKeyboardSettings = 15; +export const StartApp = 16; +export const ResetVideo = 17; diff --git a/libraries/scrcpy/src/base/control-message-type.ts b/libraries/scrcpy/src/base/control-message-type.ts index bf08d918..d38b2bb1 100644 --- a/libraries/scrcpy/src/base/control-message-type.ts +++ b/libraries/scrcpy/src/base/control-message-type.ts @@ -1,24 +1,8 @@ -// Their IDs change between versions, so always use `options.getControlMessageTypes()` -export const ScrcpyControlMessageType = { - InjectKeyCode: 0, - InjectText: 1, - InjectTouch: 2, - InjectScroll: 3, - BackOrScreenOn: 4, - ExpandNotificationPanel: 5, - ExpandSettingPanel: 6, - CollapseNotificationPanel: 7, - GetClipboard: 8, - SetClipboard: 9, - SetDisplayPower: 10, - RotateDevice: 11, - UHidCreate: 12, - UHidInput: 13, - UHidDestroy: 14, - OpenHardKeyboardSettings: 15, - StartApp: 16, - ResetVideo: 17, -} as const; +import * as ScrcpyControlMessageType from "./control-message-type-value.js"; -export type ScrcpyControlMessageType = +// These IDs change between versions, so always use `options.controlMessageTypes` +// biome-ignore lint/suspicious/noRedeclare: TypeScript declaration merging for enum-like object +type ScrcpyControlMessageType = (typeof ScrcpyControlMessageType)[keyof typeof ScrcpyControlMessageType]; + +export { ScrcpyControlMessageType }; diff --git a/libraries/scrcpy/src/base/options.ts b/libraries/scrcpy/src/base/options.ts index c25cdadb..722371a2 100644 --- a/libraries/scrcpy/src/base/options.ts +++ b/libraries/scrcpy/src/base/options.ts @@ -18,8 +18,12 @@ import type { ScrcpyMediaStreamPacket } from "./media.js"; import type { ScrcpyScrollController } from "./scroll-controller.js"; import type { ScrcpyVideoStream } from "./video.js"; +export type ScrcpyControlMessageTypeMap = Partial< + Record +>; + export interface ScrcpyOptions { - get controlMessageTypes(): readonly ScrcpyControlMessageType[]; + get controlMessageTypes(): ScrcpyControlMessageTypeMap; value: Required; diff --git a/libraries/scrcpy/src/control/index.ts b/libraries/scrcpy/src/control/index.ts index 8595d506..85aec599 100644 --- a/libraries/scrcpy/src/control/index.ts +++ b/libraries/scrcpy/src/control/index.ts @@ -1,7 +1,6 @@ export * from "./empty.js"; export * from "./inject-key-code.js"; export * from "./inject-text.js"; -export * from "./message-type-map.js"; export * from "./serializer.js"; export * from "./set-screen-power-mode.js"; export * from "./writer.js"; diff --git a/libraries/scrcpy/src/control/inject-key-code.ts b/libraries/scrcpy/src/control/inject-key-code.ts index 0040ed16..7808f10c 100644 --- a/libraries/scrcpy/src/control/inject-key-code.ts +++ b/libraries/scrcpy/src/control/inject-key-code.ts @@ -6,19 +6,18 @@ import type { AndroidKeyEventAction, AndroidKeyEventMeta, } from "../android/index.js"; -import { ScrcpyControlMessageType } from "../base/index.js"; -export const ScrcpyInjectKeyCodeControlMessage = /* #__PURE__ */ (() => - struct( - { - type: u8(ScrcpyControlMessageType.InjectKeyCode), - action: u8(), - keyCode: u32(), - repeat: u32, - metaState: u32(), - }, - { littleEndian: false }, - ))(); +export const ScrcpyInjectKeyCodeControlMessage = struct( + { + // value of `type` can change between versions + type: u8, + action: u8(), + keyCode: u32(), + repeat: u32, + metaState: u32(), + }, + { littleEndian: false }, +); export type ScrcpyInjectKeyCodeControlMessage = StructInit< typeof ScrcpyInjectKeyCodeControlMessage diff --git a/libraries/scrcpy/src/control/inject-text.ts b/libraries/scrcpy/src/control/inject-text.ts index 594150de..2f022c8b 100644 --- a/libraries/scrcpy/src/control/inject-text.ts +++ b/libraries/scrcpy/src/control/inject-text.ts @@ -2,7 +2,11 @@ import type { StructInit } from "@yume-chan/struct"; import { string, struct, u32, u8 } from "@yume-chan/struct"; export const ScrcpyInjectTextControlMessage = struct( - { type: u8, text: string(u32) }, + { + // value of `type` can change between versions + type: u8, + text: string(u32), + }, { littleEndian: false }, ); diff --git a/libraries/scrcpy/src/control/message-type-map.ts b/libraries/scrcpy/src/control/message-type-map.ts deleted file mode 100644 index ce5a5f2e..00000000 --- a/libraries/scrcpy/src/control/message-type-map.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { ScrcpyControlMessageType, ScrcpyOptions } from "../base/index.js"; - -/** - * Scrcpy control message types have different values between versions. - * - * This class provides a way to get the actual value for a given type. - */ -export class ScrcpyControlMessageTypeMap { - #types: readonly ScrcpyControlMessageType[]; - - constructor(options: ScrcpyOptions) { - this.#types = options.controlMessageTypes; - } - - get(type: ScrcpyControlMessageType): number { - const value = this.#types.indexOf(type); - if (value === -1) { - throw new TypeError("Invalid or unsupported control message type"); - } - return value; - } - - fillMessageType( - message: Omit, - type: ScrcpyControlMessageType, - ): T { - (message as T).type = this.get(type); - return message as T; - } -} diff --git a/libraries/scrcpy/src/control/serializer.ts b/libraries/scrcpy/src/control/serializer.ts index 2c72394b..c8fee63c 100644 --- a/libraries/scrcpy/src/control/serializer.ts +++ b/libraries/scrcpy/src/control/serializer.ts @@ -14,7 +14,6 @@ import type { import { EmptyControlMessage } from "./empty.js"; import { ScrcpyInjectKeyCodeControlMessage } from "./inject-key-code.js"; import { ScrcpyInjectTextControlMessage } from "./inject-text.js"; -import { ScrcpyControlMessageTypeMap } from "./message-type-map.js"; import { ScrcpySetDisplayPowerControlMessage } from "./set-screen-power-mode.js"; import { ScrcpyStartAppControlMessage } from "./start-app.js"; import { @@ -24,28 +23,39 @@ import { export class ScrcpyControlMessageSerializer { #options: ScrcpyOptions; - #typeMap: ScrcpyControlMessageTypeMap; #scrollController: ScrcpyScrollController; constructor(options: ScrcpyOptions) { this.#options = options; - this.#typeMap = new ScrcpyControlMessageTypeMap(options); this.#scrollController = options.createScrollController(); } + getType(type: ScrcpyControlMessageType): number { + const value = this.#options.controlMessageTypes[type]; + if (value === undefined) { + throw new TypeError(`Invalid control message type: ${type}`); + } + return value; + } + + #addType( + message: Omit, + type: ScrcpyControlMessageType, + ): T { + (message as T).type = this.getType(type); + return message as T; + } + injectKeyCode(message: Omit) { return ScrcpyInjectKeyCodeControlMessage.serialize( - this.#typeMap.fillMessageType( - message, - ScrcpyControlMessageType.InjectKeyCode, - ), + this.#addType(message, ScrcpyControlMessageType.InjectKeyCode), ); } injectText(text: string) { return ScrcpyInjectTextControlMessage.serialize({ text, - type: this.#typeMap.get(ScrcpyControlMessageType.InjectText), + type: this.getType(ScrcpyControlMessageType.InjectText), }); } @@ -54,10 +64,7 @@ export class ScrcpyControlMessageSerializer { */ injectTouch(message: Omit) { return this.#options.serializeInjectTouchControlMessage( - this.#typeMap.fillMessageType( - message, - ScrcpyControlMessageType.InjectTouch, - ), + this.#addType(message, ScrcpyControlMessageType.InjectTouch), ); } @@ -66,30 +73,27 @@ export class ScrcpyControlMessageSerializer { */ injectScroll(message: Omit) { return this.#scrollController.serializeScrollMessage( - this.#typeMap.fillMessageType( - message, - ScrcpyControlMessageType.InjectScroll, - ), + this.#addType(message, ScrcpyControlMessageType.InjectScroll), ); } backOrScreenOn(action: AndroidKeyEventAction) { return this.#options.serializeBackOrScreenOnControlMessage({ action, - type: this.#typeMap.get(ScrcpyControlMessageType.BackOrScreenOn), + type: this.getType(ScrcpyControlMessageType.BackOrScreenOn), }); } setDisplayPower(mode: AndroidScreenPowerMode) { return ScrcpySetDisplayPowerControlMessage.serialize({ mode, - type: this.#typeMap.get(ScrcpyControlMessageType.SetDisplayPower), + type: this.getType(ScrcpyControlMessageType.SetDisplayPower), }); } expandNotificationPanel() { return EmptyControlMessage.serialize({ - type: this.#typeMap.get( + type: this.getType( ScrcpyControlMessageType.ExpandNotificationPanel, ), }); @@ -97,15 +101,13 @@ export class ScrcpyControlMessageSerializer { expandSettingPanel() { return EmptyControlMessage.serialize({ - type: this.#typeMap.get( - ScrcpyControlMessageType.ExpandSettingPanel, - ), + type: this.getType(ScrcpyControlMessageType.ExpandSettingPanel), }); } collapseNotificationPanel() { return EmptyControlMessage.serialize({ - type: this.#typeMap.get( + type: this.getType( ScrcpyControlMessageType.CollapseNotificationPanel, ), }); @@ -113,14 +115,14 @@ export class ScrcpyControlMessageSerializer { rotateDevice() { return EmptyControlMessage.serialize({ - type: this.#typeMap.get(ScrcpyControlMessageType.RotateDevice), + type: this.getType(ScrcpyControlMessageType.RotateDevice), }); } setClipboard(message: Omit) { return this.#options.serializeSetClipboardControlMessage({ ...message, - type: this.#typeMap.get(ScrcpyControlMessageType.SetClipboard), + type: this.getType(ScrcpyControlMessageType.SetClipboard), }); } @@ -130,25 +132,19 @@ export class ScrcpyControlMessageSerializer { } return this.#options.serializeUHidCreateControlMessage( - this.#typeMap.fillMessageType( - message, - ScrcpyControlMessageType.UHidCreate, - ), + this.#addType(message, ScrcpyControlMessageType.UHidCreate), ); } uHidInput(message: Omit) { return ScrcpyUHidInputControlMessage.serialize( - this.#typeMap.fillMessageType( - message, - ScrcpyControlMessageType.UHidInput, - ), + this.#addType(message, ScrcpyControlMessageType.UHidInput), ); } uHidDestroy(id: number) { return ScrcpyUHidDestroyControlMessage.serialize({ - type: this.#typeMap.get(ScrcpyControlMessageType.UHidDestroy), + type: this.getType(ScrcpyControlMessageType.UHidDestroy), id, }); } @@ -165,14 +161,14 @@ export class ScrcpyControlMessageSerializer { } return ScrcpyStartAppControlMessage.serialize({ - type: this.#typeMap.get(ScrcpyControlMessageType.StartApp), + type: this.getType(ScrcpyControlMessageType.StartApp), name, }); } resetVideo() { return EmptyControlMessage.serialize({ - type: this.#typeMap.get(ScrcpyControlMessageType.ResetVideo), + type: this.getType(ScrcpyControlMessageType.ResetVideo), }); } } diff --git a/libraries/scrcpy/src/control/set-screen-power-mode.ts b/libraries/scrcpy/src/control/set-screen-power-mode.ts index b81b7505..0a5a5bee 100644 --- a/libraries/scrcpy/src/control/set-screen-power-mode.ts +++ b/libraries/scrcpy/src/control/set-screen-power-mode.ts @@ -4,7 +4,11 @@ import { struct, u8 } from "@yume-chan/struct"; import type { AndroidScreenPowerMode } from "../android/index.js"; export const ScrcpySetDisplayPowerControlMessage = struct( - { type: u8, mode: u8() }, + { + // value of `type` can change between versions + type: u8, + mode: u8(), + }, { littleEndian: false }, ); diff --git a/libraries/scrcpy/src/control/start-app.ts b/libraries/scrcpy/src/control/start-app.ts index 4f3ef902..7702780b 100644 --- a/libraries/scrcpy/src/control/start-app.ts +++ b/libraries/scrcpy/src/control/start-app.ts @@ -3,6 +3,7 @@ import { string, struct, u8 } from "@yume-chan/struct"; export const ScrcpyStartAppControlMessage = struct( { + // value of `type` can change between versions type: u8, name: string(u8), }, diff --git a/libraries/scrcpy/src/control/uhid.ts b/libraries/scrcpy/src/control/uhid.ts index a40dc451..22dfc987 100644 --- a/libraries/scrcpy/src/control/uhid.ts +++ b/libraries/scrcpy/src/control/uhid.ts @@ -1,24 +1,26 @@ import type { StructInit } from "@yume-chan/struct"; import { buffer, struct, u16, u8 } from "@yume-chan/struct"; -import { ScrcpyControlMessageType } from "../base/index.js"; - -export const ScrcpyUHidInputControlMessage = /* #__PURE__ */ (() => - struct( - { - type: u8(ScrcpyControlMessageType.UHidInput), - id: u16, - data: buffer(u16), - }, - { littleEndian: false }, - ))(); +export const ScrcpyUHidInputControlMessage = struct( + { + // value of `type` can change between versions + type: u8, + id: u16, + data: buffer(u16), + }, + { littleEndian: false }, +); export type ScrcpyUHidInputControlMessage = StructInit< typeof ScrcpyUHidInputControlMessage >; export const ScrcpyUHidDestroyControlMessage = struct( - { type: u8, id: u16 }, + { + // value of `type` can change between versions + type: u8, + id: u16, + }, { littleEndian: false }, ); diff --git a/libraries/scrcpy/src/latest.ts b/libraries/scrcpy/src/latest.ts index 7ce9a3b4..256f2344 100644 --- a/libraries/scrcpy/src/latest.ts +++ b/libraries/scrcpy/src/latest.ts @@ -1,17 +1,4 @@ -import { ScrcpyOptions3_3_2 } from "./3_3_2.js"; - -export class ScrcpyOptionsLatest< - TVideo extends boolean, -> extends ScrcpyOptions3_3_2 { - constructor(init: ScrcpyOptions3_3_2.Init) { - super(init); - } -} - -export namespace ScrcpyOptionsLatest { - export type Init = - ScrcpyOptions3_3_2.Init; -} +export { ScrcpyOptions3_3_2 as ScrcpyOptionsLatest } from "./3_3_2.js"; export { BackOrScreenOnControlMessage as ScrcpyBackOrScreenOnControlMessage, diff --git a/libraries/struct/src/bipedal.ts b/libraries/struct/src/bipedal.ts index 56588659..b37ac06b 100644 --- a/libraries/struct/src/bipedal.ts +++ b/libraries/struct/src/bipedal.ts @@ -24,7 +24,7 @@ export type BipedalGenerator = ( this: This, then: (value: MaybePromiseLike) => Iterable, ...args: A -) => Generator; +) => Generator, unknown>; /* #__NO_SIDE_EFFECTS__ */ export function bipedal( diff --git a/libraries/struct/src/buffer.ts b/libraries/struct/src/buffer.ts index 8158dae9..92a57a4a 100644 --- a/libraries/struct/src/buffer.ts +++ b/libraries/struct/src/buffer.ts @@ -1,22 +1,26 @@ -import type { Field } from "./field/index.js"; +import type { + BipedalFieldDeserializer, + ByobFieldSerializer, + Field, +} from "./field/index.js"; import { field } from "./field/index.js"; export const EmptyUint8Array = new Uint8Array(0); function copyMaybeDifferentLength( - dist: Uint8Array, + dest: Uint8Array, source: Uint8Array, index: number, length: number, ) { if (source.length < length) { - dist.set(source, index); + dest.set(source, index); // Clear trailing bytes - dist.fill(0, index + source.length, index + length); + dest.fill(0, index + source.length, index + length); } else if (source.length === length) { - dist.set(source, index); + dest.set(source, index); } else { - dist.set(source.subarray(0, length), index); + dest.set(source.subarray(0, length), index); } } @@ -29,70 +33,97 @@ export interface BufferLengthConverter extends Converter { field: K; } -export interface BufferLike { - (length: number): Field; - ( - length: number, - converter: Converter, - ): Field; - - ( - lengthField: K, - ): Field, Uint8Array>; - ( - lengthField: K, - converter: Converter, - ): Field, Uint8Array>; - - ( - length: BufferLengthConverter, - ): Field, Uint8Array>; - ( - length: BufferLengthConverter, - converter: Converter, - ): Field, Uint8Array>; - - ( - length: Field, - ): Field; - ( - length: Field, - converter: Converter, - ): Field; -} - -function _buffer(length: number): Field; -function _buffer( +/** + * Create a fixed-length `Uint8Array` field. + * + * @param length Length of the field + */ +export function buffer( + length: number, +): Field; +/** + * Create a custom-typed field, backed by a fixed-length `Uint8Array`. + * + * @param length Length of the field + * @param converter A value converter to convert between `Uint8Array` and the target type + */ +export function buffer( length: number, converter: Converter, ): Field; -function _buffer( +/** + * Create a variable-length `Uint8Array` field. + * The length is determined by another number-typed field. + * + * @param lengthField Name of the length field. Must be declared before this field + */ +export function buffer( lengthField: K, ): Field, Uint8Array>; -function _buffer( +/** + * Create a custom-typed field, backed by a variable-length `Uint8Array`. + * The length is determined by another number-typed field. + * + * @param lengthField Name of the length field. Must be declared before this field + * @param converter A value converter to convert between `Uint8Array` and the target type + */ +export function buffer( lengthField: K, converter: Converter, ): Field, Uint8Array>; -function _buffer( +/** + * Create a variable-length `Uint8Array` field. + * The length is determined by converting another field to `number`. + * + * @param length + * Name of the length field, + * and a converter to convert between source type and `number`. + * Must be declared before this field + */ +export function buffer( length: BufferLengthConverter, ): Field, Uint8Array>; -function _buffer( +/** + * Create a custom-typed field, backed by a variable-length `Uint8Array`. + * The length is determined by converting another field to `number`. + * + * @param length + * Name of the length field, + * and a converter to convert between source type and `number`. + * Must be declared before this field + * @param converter + * A value converter to convert between `Uint8Array` and the target type + */ +export function buffer( length: BufferLengthConverter, converter: Converter, ): Field, Uint8Array>; -function _buffer( +/** + * Create a length field, and a variable-length `Uint8Array` field. + * This is a shortcut when the length field is directly before the data field. + * + * @param length The length field declaration + */ +export function buffer( length: Field, ): Field; -function _buffer( +/** + * Create a length field, and a custom-typed field, backed by a variable-length `Uint8Array`. + * This is a shortcut when the length field is directly before the data field. + * + * @param length The length field declaration + * @param converter A value converter to convert between `Uint8Array` and the target type + */ +export function buffer( length: Field, converter: Converter, ): Field; /* #__NO_SIDE_EFFECTS__ */ -function _buffer( +export function buffer( lengthOrField: | string | number @@ -102,67 +133,47 @@ function _buffer( ): Field, Uint8Array> { // Fixed length if (typeof lengthOrField === "number") { - if (converter) { - if (lengthOrField === 0) { - return field( - 0, - "byob", - () => {}, - // eslint-disable-next-line require-yield - function* () { - return converter.convert(EmptyUint8Array); - }, - ); - } - - return field( - lengthOrField, - "byob", - (value, { buffer, index }) => { - copyMaybeDifferentLength( - buffer, - value, - index, - lengthOrField, - ); - }, - function* (then, reader) { - const array = yield* then( - reader.readExactly(lengthOrField), - ); - return converter.convert(array); - }, - { - init(value) { - return converter.back(value); - }, - }, - ); - } + let serialize: ByobFieldSerializer; + let deserialize: BipedalFieldDeserializer< + unknown, + Record + >; + let init: ((value: unknown) => Uint8Array) | undefined; if (lengthOrField === 0) { - return field( - 0, - "byob", - () => {}, + serialize = () => {}; + + if (converter) { // eslint-disable-next-line require-yield - function* () { + deserialize = function* () { + return converter.convert(EmptyUint8Array); + }; + } else { + // eslint-disable-next-line require-yield + deserialize = function* () { return EmptyUint8Array; - }, - ); + }; + } + } else { + serialize = (value, { buffer, index }) => + copyMaybeDifferentLength(buffer, value, index, lengthOrField); + + if (converter) { + deserialize = function* (then, reader) { + const array = reader.readExactly(lengthOrField); + return converter.convert(yield* then(array)); + }; + init = (value) => converter.back(value); + } else { + // eslint-disable-next-line require-yield + deserialize = function* (_then, reader) { + const array = reader.readExactly(lengthOrField); + return array; + }; + } } - return field( - lengthOrField, - "byob", - (value, { buffer, index }) => { - copyMaybeDifferentLength(buffer, value, index, lengthOrField); - }, - // eslint-disable-next-line require-yield - function* (_then, reader) { - return reader.readExactly(lengthOrField); - }, - ); + return field(lengthOrField, "byob", serialize, deserialize, { init }); } // Declare length field @@ -172,48 +183,31 @@ function _buffer( typeof lengthOrField === "function") && "serialize" in lengthOrField ) { + let deserialize: BipedalFieldDeserializer< + unknown, + Record + >; + let init: ((value: unknown) => Uint8Array) | undefined; + if (converter) { - return field( - lengthOrField.size, - "default", - (value, { littleEndian }) => { - if (lengthOrField.type === "default") { - const lengthBuffer = lengthOrField.serialize( - value.length, - { littleEndian }, - ); - const result = new Uint8Array( - lengthBuffer.length + value.length, - ); - result.set(lengthBuffer, 0); - result.set(value, lengthBuffer.length); - return result; - } else { - const result = new Uint8Array( - lengthOrField.size + value.length, - ); - lengthOrField.serialize(value.length, { - buffer: result, - index: 0, - littleEndian, - }); - result.set(value, lengthOrField.size); - return result; - } - }, - function* (then, reader, context) { - const length = yield* then( - lengthOrField.deserialize(reader, context), - ); - const array = yield* then(reader.readExactly(length)); - return converter.convert(array); - }, - { - init(value) { - return converter.back(value); - }, - }, - ); + deserialize = function* (then, reader, context) { + const length = yield* then( + lengthOrField.deserialize(reader, context), + ); + const array = + length !== 0 ? reader.readExactly(length) : EmptyUint8Array; + return converter.convert(yield* then(array)); + }; + init = (value) => converter.back(value); + } else { + deserialize = function* (then, reader, context) { + const length = yield* then( + lengthOrField.deserialize(reader, context), + ); + const array = + length !== 0 ? reader.readExactly(length) : EmptyUint8Array; + return array; + }; } return field( @@ -224,6 +218,11 @@ function _buffer( const lengthBuffer = lengthOrField.serialize(value.length, { littleEndian, }); + + if (value.length === 0) { + return lengthBuffer; + } + const result = new Uint8Array( lengthBuffer.length + value.length, ); @@ -243,114 +242,91 @@ function _buffer( return result; } }, - function* (then, reader, context) { - const length = yield* then( - lengthOrField.deserialize(reader, context), - ); - return yield* then(reader.readExactly(length)); - }, + deserialize, + { init }, ); } - // Reference exiting length field + // Reference existing length field if (typeof lengthOrField === "string") { - if (converter) { - return field( - 0, - "default", - (source) => source, - // eslint-disable-next-line require-yield - function* (_then, reader, { dependencies }) { - const length = dependencies[lengthOrField] as number; - if (length === 0) { - return EmptyUint8Array; - } + let deserialize: BipedalFieldDeserializer< + unknown, + Record + >; + let init: ( + value: unknown, + dependencies: Record, + ) => Uint8Array; - return reader.readExactly(length); - }, - { - init(value, dependencies) { - const array = converter.back(value); - dependencies[lengthOrField] = array.length; - return array; - }, - }, - ); + if (converter) { + deserialize = function* (then, reader, { dependencies }) { + const length = dependencies[lengthOrField] as number; + const array = + length !== 0 ? reader.readExactly(length) : EmptyUint8Array; + return converter.convert(yield* then(array)); + }; + init = (value, dependencies) => { + const array = converter.back(value); + dependencies[lengthOrField] = array.length; + return array; + }; + } else { + // eslint-disable-next-line require-yield + deserialize = function* (_then, reader, { dependencies }) { + const length = dependencies[lengthOrField] as number; + const array = + length !== 0 ? reader.readExactly(length) : EmptyUint8Array; + return array; + }; + init = (value, dependencies) => { + const array = value as Uint8Array; + dependencies[lengthOrField] = array.length; + return array; + }; } - return field( - 0, - "default", - (source) => source, - // eslint-disable-next-line require-yield - function* (_then, reader, { dependencies }) { - const length = dependencies[lengthOrField] as number; - if (length === 0) { - return EmptyUint8Array; - } - - return reader.readExactly(length); - }, - { - init(value, dependencies) { - dependencies[lengthOrField] = (value as Uint8Array).length; - return undefined; - }, - }, - ); + return field(0, "default", (source) => source, deserialize, { init }); } - // Reference existing length field + converter + let deserialize: BipedalFieldDeserializer>; + let init: ( + value: unknown, + dependencies: Record, + ) => Uint8Array; + + // Reference existing length field + length converter if (converter) { - return field( - 0, - "default", - (source) => source, - // eslint-disable-next-line require-yield - function* (_then, reader, { dependencies }) { - const rawLength = dependencies[lengthOrField.field]; - const length = lengthOrField.convert(rawLength); - if (length === 0) { - return EmptyUint8Array; - } - - return reader.readExactly(length); - }, - { - init(value, dependencies) { - const array = converter.back(value); - dependencies[lengthOrField.field] = lengthOrField.back( - array.length, - ); - return array; - }, - }, - ); - } - - return field( - 0, - "default", - (source) => source, - // eslint-disable-next-line require-yield - function* (_then, reader, { dependencies }) { + deserialize = function* (then, reader, { dependencies }) { const rawLength = dependencies[lengthOrField.field]; const length = lengthOrField.convert(rawLength); - if (length === 0) { - return EmptyUint8Array; - } + const array = + length !== 0 ? reader.readExactly(length) : EmptyUint8Array; + return converter.convert(yield* then(array)); + }; + init = (value, dependencies) => { + const array = converter.back(value); + dependencies[lengthOrField.field] = lengthOrField.back( + array.length, + ); + return array; + }; + } else { + // eslint-disable-next-line require-yield + deserialize = function* (_then, reader, { dependencies }) { + const rawLength = dependencies[lengthOrField.field]; + const length = lengthOrField.convert(rawLength); + const array = + length !== 0 ? reader.readExactly(length) : EmptyUint8Array; + return array; + }; + init = (value, dependencies) => { + const array = value as Uint8Array; + dependencies[lengthOrField.field] = lengthOrField.back( + array.length, + ); + return array; + }; + } - return reader.readExactly(length); - }, - { - init(value, dependencies) { - dependencies[lengthOrField.field] = lengthOrField.back( - (value as Uint8Array).length, - ); - return undefined; - }, - }, - ); + return field(0, "default", (source) => source, deserialize, { init }); } - -export const buffer = _buffer; diff --git a/libraries/struct/src/field/types.ts b/libraries/struct/src/field/types.ts index 5b520942..17694c5d 100644 --- a/libraries/struct/src/field/types.ts +++ b/libraries/struct/src/field/types.ts @@ -25,7 +25,10 @@ export interface Field FieldDeserializer { omitInit: OmitInit | undefined; - init?(value: T, dependencies: D): Raw | undefined; + /** + * A function to convert deserialized value back to raw value for serialization. + */ + init?(value: T, dependencies: D): Raw; } export interface FieldDeserializeContext { @@ -44,5 +47,8 @@ export interface FieldDeserializer { export interface FieldOptions { omitInit?: OmitInit; dependencies?: D; - init?: (value: T, dependencies: D) => Raw | undefined; + /** + * A function to convert deserialized value back to raw value for serialization. + */ + init?: ((value: T, dependencies: D) => Raw) | undefined; } diff --git a/libraries/struct/src/struct.ts b/libraries/struct/src/struct.ts index 6c169032..2c01d32f 100644 --- a/libraries/struct/src/struct.ts +++ b/libraries/struct/src/struct.ts @@ -132,9 +132,7 @@ export function struct< for (const [key, field] of fieldList) { if (key in temp && "init" in field) { const result = field.init?.(temp[key], temp as never); - if (result !== undefined) { - temp[key] = result; - } + temp[key] = result; } } diff --git a/toolchain/side-effect-test/README.md b/toolchain/side-effect-test/README.md new file mode 100644 index 00000000..05d4e142 --- /dev/null +++ b/toolchain/side-effect-test/README.md @@ -0,0 +1,3 @@ +# Side effect test + +Use Rollup's `experimentalLogSideEffects` to log any side effects in exports. diff --git a/toolchain/side-effect-test/generate.mjs b/toolchain/side-effect-test/generate.mjs new file mode 100644 index 00000000..caa862b6 --- /dev/null +++ b/toolchain/side-effect-test/generate.mjs @@ -0,0 +1,34 @@ +import { writeFileSync } from "node:fs"; +import { dirname, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +async function generateTest(packageName, filename) { + const exports = await import(packageName); + const names = Object.keys(exports) + .filter( + (name) => + name !== "default" && name !== "__esModule" && name !== "then", + ) + .sort(); + + writeFileSync( + resolve(dirname(fileURLToPath(import.meta.url)), filename), + ` +// Generated by toolchain/side-effect-test/generate.mjs +// DO NOT MODIFY THIS FILE MANUALLY +/* eslint-disable */ + +import { ${names.join(", ")} } from "${packageName}"; + +export default () => { + console.log(${names.join(", ")}) +} +`, + "utf8", + ); +} + +await Promise.all([ + generateTest("@yume-chan/scrcpy", "./src/scrcpy.js"), + generateTest("@yume-chan/adb", "./src/adb.js"), +]); diff --git a/toolchain/side-effect-test/rollup.config.ts b/toolchain/side-effect-test/rollup.config.ts index 8bd1be31..aea069d6 100644 --- a/toolchain/side-effect-test/rollup.config.ts +++ b/toolchain/side-effect-test/rollup.config.ts @@ -1,4 +1,5 @@ import node from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; import typescript from "@rollup/plugin-typescript"; import { defineConfig } from "rollup"; @@ -13,11 +14,15 @@ export default defineConfig({ plugins: [ typescript(), node(), - // terser({ - // module: true, - // format: { - // beautify: true, - // }, - // }), + terser({ + module: true, + format: { + beautify: true, + }, + compress: { + passes: 10, + }, + mangle: false, + }), ], }); diff --git a/toolchain/side-effect-test/src/adb.js b/toolchain/side-effect-test/src/adb.js new file mode 100644 index 00000000..46da3b4e --- /dev/null +++ b/toolchain/side-effect-test/src/adb.js @@ -0,0 +1,10 @@ + +// Generated by toolchain/side-effect-test/generate.mjs +// DO NOT MODIFY THIS FILE MANUALLY +/* eslint-disable */ + +import { ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE, ADB_DAEMON_VERSION_OMIT_CHECKSUM, ADB_SYNC_MAX_PACKET_SIZE, ASN1_NULL, ASN1_OCTET_STRING, ASN1_OID, ASN1_SEQUENCE, Adb, AdbAuthType, AdbBanner, AdbBannerKey, AdbCommand, AdbDaemonSocket, AdbDaemonSocketController, AdbDaemonTransport, AdbDefaultAuthenticator, AdbDeviceFeatures, AdbFeature, AdbFrameBufferError, AdbFrameBufferForbiddenError, AdbFrameBufferUnsupportedVersionError, AdbFrameBufferV1, AdbFrameBufferV2, AdbNoneProtocolProcessImpl, AdbNoneProtocolPtyProcess, AdbNoneProtocolSubprocessService, AdbPacket, AdbPacketDispatcher, AdbPacketHeader, AdbPacketSerializeStream, AdbPower, AdbReverseError, AdbReverseNotSupportedError, AdbReverseService, AdbServerClient, AdbServerDeviceObserverOwner, AdbServerStream, AdbServerTransport, AdbServiceBase, AdbShellProtocolId, AdbShellProtocolPacket, AdbShellProtocolProcessImpl, AdbShellProtocolPtyProcess, AdbShellProtocolSubprocessService, AdbSubprocessService, AdbSync, AdbSyncDataResponse, AdbSyncEntry2Response, AdbSyncEntryResponse, AdbSyncError, AdbSyncFailResponse, AdbSyncLstatResponse, AdbSyncNumberRequest, AdbSyncOkResponse, AdbSyncRequestId, AdbSyncResponseId, AdbSyncSendV2Flags, AdbSyncSendV2Request, AdbSyncSocket, AdbSyncSocketLocked, AdbSyncStatErrorCode, AdbSyncStatResponse, AdbTcpIpService, AutoResetEvent, FAIL, LinuxFileType, NOOP, Ref, SHA1_DIGEST_INFO, SHA1_DIGEST_LENGTH, ToArrayStream, adbGeneratePublicKey, adbGetPublicKeySize, adbNoneProtocolSpawner, adbShellProtocolSpawner, adbSyncLstat, adbSyncOpenDir, adbSyncOpenDirV1, adbSyncOpenDirV2, adbSyncPull, adbSyncPullGenerator, adbSyncPush, adbSyncPushV1, adbSyncPushV2, adbSyncReadResponse, adbSyncReadResponses, adbSyncStat, adbSyncWriteRequest, calculateBase64EncodedLength, calculateChecksum, createLazyPromise, decodeBase64, decodeUtf8, decodeUtf8Chunked, dirname, encodeBase64, encodeUtf8, escapeArg, framebuffer, getBigUint, hexToNumber, modInverse, powMod, raceSignal, rsaParsePrivateKey, rsaSign, sequenceEqual, setBigUint, splitCommand, toLocalUint8Array, unorderedRemove, unreachable, write4HexDigits } from "@yume-chan/adb"; + +export default () => { + console.log(ADB_DAEMON_DEFAULT_INITIAL_PAYLOAD_SIZE, ADB_DAEMON_VERSION_OMIT_CHECKSUM, ADB_SYNC_MAX_PACKET_SIZE, ASN1_NULL, ASN1_OCTET_STRING, ASN1_OID, ASN1_SEQUENCE, Adb, AdbAuthType, AdbBanner, AdbBannerKey, AdbCommand, AdbDaemonSocket, AdbDaemonSocketController, AdbDaemonTransport, AdbDefaultAuthenticator, AdbDeviceFeatures, AdbFeature, AdbFrameBufferError, AdbFrameBufferForbiddenError, AdbFrameBufferUnsupportedVersionError, AdbFrameBufferV1, AdbFrameBufferV2, AdbNoneProtocolProcessImpl, AdbNoneProtocolPtyProcess, AdbNoneProtocolSubprocessService, AdbPacket, AdbPacketDispatcher, AdbPacketHeader, AdbPacketSerializeStream, AdbPower, AdbReverseError, AdbReverseNotSupportedError, AdbReverseService, AdbServerClient, AdbServerDeviceObserverOwner, AdbServerStream, AdbServerTransport, AdbServiceBase, AdbShellProtocolId, AdbShellProtocolPacket, AdbShellProtocolProcessImpl, AdbShellProtocolPtyProcess, AdbShellProtocolSubprocessService, AdbSubprocessService, AdbSync, AdbSyncDataResponse, AdbSyncEntry2Response, AdbSyncEntryResponse, AdbSyncError, AdbSyncFailResponse, AdbSyncLstatResponse, AdbSyncNumberRequest, AdbSyncOkResponse, AdbSyncRequestId, AdbSyncResponseId, AdbSyncSendV2Flags, AdbSyncSendV2Request, AdbSyncSocket, AdbSyncSocketLocked, AdbSyncStatErrorCode, AdbSyncStatResponse, AdbTcpIpService, AutoResetEvent, FAIL, LinuxFileType, NOOP, Ref, SHA1_DIGEST_INFO, SHA1_DIGEST_LENGTH, ToArrayStream, adbGeneratePublicKey, adbGetPublicKeySize, adbNoneProtocolSpawner, adbShellProtocolSpawner, adbSyncLstat, adbSyncOpenDir, adbSyncOpenDirV1, adbSyncOpenDirV2, adbSyncPull, adbSyncPullGenerator, adbSyncPush, adbSyncPushV1, adbSyncPushV2, adbSyncReadResponse, adbSyncReadResponses, adbSyncStat, adbSyncWriteRequest, calculateBase64EncodedLength, calculateChecksum, createLazyPromise, decodeBase64, decodeUtf8, decodeUtf8Chunked, dirname, encodeBase64, encodeUtf8, escapeArg, framebuffer, getBigUint, hexToNumber, modInverse, powMod, raceSignal, rsaParsePrivateKey, rsaSign, sequenceEqual, setBigUint, splitCommand, toLocalUint8Array, unorderedRemove, unreachable, write4HexDigits) +} diff --git a/toolchain/side-effect-test/src/index.js b/toolchain/side-effect-test/src/index.js index af429790..573fb07c 100644 --- a/toolchain/side-effect-test/src/index.js +++ b/toolchain/side-effect-test/src/index.js @@ -1,42 +1,2 @@ -import { - bipedal, - buffer, - concat, - decodeUtf8, - encodeUtf8, - extend, - s16, - s32, - s64, - s8, - string, - struct, - u16, - u32, - u64, - u8, -} from "@yume-chan/struct"; - -bipedal(function* () {}); -buffer(u8); -decodeUtf8(new Uint8Array()); -encodeUtf8(""); -s16(1); -s32(1); -s64(1); -s8(1); -string(1); -u16(1); -u32(1); -u64(1); -u8(1); -struct({}, { littleEndian: true }); -concat( - { littleEndian: true }, - struct({ a: u8 }, { littleEndian: true }), - struct({ b: u8 }, { littleEndian: true }), -); -extend(struct({ a: u16 }, { littleEndian: true }), { b: buffer(32) }); - -export * from "@yume-chan/scrcpy"; -export * from "@yume-chan/struct"; +export { default as Adb } from "./adb.js"; +export { default as Scrcpy } from "./scrcpy.js"; diff --git a/toolchain/side-effect-test/src/scrcpy.js b/toolchain/side-effect-test/src/scrcpy.js new file mode 100644 index 00000000..59469c56 --- /dev/null +++ b/toolchain/side-effect-test/src/scrcpy.js @@ -0,0 +1,10 @@ + +// Generated by toolchain/side-effect-test/generate.mjs +// DO NOT MODIFY THIS FILE MANUALLY +/* eslint-disable */ + +import { AndroidAvcLevel, AndroidAvcProfile, AndroidHevcLevel, AndroidHevcProfile, AndroidKeyCode, AndroidKeyEventAction, AndroidKeyEventMeta, AndroidKeyNames, AndroidMotionEventAction, AndroidMotionEventButton, AndroidScreenPowerMode, DefaultServerPath, EmptyControlMessage, ScrcpyAudioCodec, ScrcpyBackOrScreenOnControlMessage, ScrcpyCaptureOrientation, ScrcpyCodecOptions, ScrcpyControlMessageSerializer, ScrcpyControlMessageType, ScrcpyControlMessageWriter, ScrcpyCrop, ScrcpyDeviceMessageParsers, ScrcpyInjectKeyCodeControlMessage, ScrcpyInjectScrollControlMessage, ScrcpyInjectTextControlMessage, ScrcpyInjectTouchControlMessage, ScrcpyInstanceId, ScrcpyLockOrientation, ScrcpyNewDisplay, ScrcpyOptions1_15, ScrcpyOptions1_15_1, ScrcpyOptions1_16, ScrcpyOptions1_17, ScrcpyOptions1_18, ScrcpyOptions1_19, ScrcpyOptions1_20, ScrcpyOptions1_21, ScrcpyOptions1_22, ScrcpyOptions1_23, ScrcpyOptions1_24, ScrcpyOptions1_25, ScrcpyOptions2_0, ScrcpyOptions2_1, ScrcpyOptions2_1_1, ScrcpyOptions2_2, ScrcpyOptions2_3, ScrcpyOptions2_3_1, ScrcpyOptions2_4, ScrcpyOptions2_5, ScrcpyOptions2_6, ScrcpyOptions2_6_1, ScrcpyOptions2_7, ScrcpyOptions3_0, ScrcpyOptions3_0_1, ScrcpyOptions3_0_2, ScrcpyOptions3_1, ScrcpyOptions3_2, ScrcpyOptions3_3, ScrcpyOptions3_3_1, ScrcpyOptions3_3_2, ScrcpyOptionsLatest, ScrcpyOrientation, ScrcpyPointerId, ScrcpySetClipboardControlMessage, ScrcpySetDisplayPowerControlMessage, ScrcpyUHidCreateControlMessage, ScrcpyUHidOutputDeviceMessage, ScrcpyVideoCodecId, ScrcpyVideoCodecNameMap, ScrcpyVideoSizeImpl, clamp, isScrcpyOptionValue, omit, toScrcpyOptionValue } from "@yume-chan/scrcpy"; + +export default () => { + console.log(AndroidAvcLevel, AndroidAvcProfile, AndroidHevcLevel, AndroidHevcProfile, AndroidKeyCode, AndroidKeyEventAction, AndroidKeyEventMeta, AndroidKeyNames, AndroidMotionEventAction, AndroidMotionEventButton, AndroidScreenPowerMode, DefaultServerPath, EmptyControlMessage, ScrcpyAudioCodec, ScrcpyBackOrScreenOnControlMessage, ScrcpyCaptureOrientation, ScrcpyCodecOptions, ScrcpyControlMessageSerializer, ScrcpyControlMessageType, ScrcpyControlMessageWriter, ScrcpyCrop, ScrcpyDeviceMessageParsers, ScrcpyInjectKeyCodeControlMessage, ScrcpyInjectScrollControlMessage, ScrcpyInjectTextControlMessage, ScrcpyInjectTouchControlMessage, ScrcpyInstanceId, ScrcpyLockOrientation, ScrcpyNewDisplay, ScrcpyOptions1_15, ScrcpyOptions1_15_1, ScrcpyOptions1_16, ScrcpyOptions1_17, ScrcpyOptions1_18, ScrcpyOptions1_19, ScrcpyOptions1_20, ScrcpyOptions1_21, ScrcpyOptions1_22, ScrcpyOptions1_23, ScrcpyOptions1_24, ScrcpyOptions1_25, ScrcpyOptions2_0, ScrcpyOptions2_1, ScrcpyOptions2_1_1, ScrcpyOptions2_2, ScrcpyOptions2_3, ScrcpyOptions2_3_1, ScrcpyOptions2_4, ScrcpyOptions2_5, ScrcpyOptions2_6, ScrcpyOptions2_6_1, ScrcpyOptions2_7, ScrcpyOptions3_0, ScrcpyOptions3_0_1, ScrcpyOptions3_0_2, ScrcpyOptions3_1, ScrcpyOptions3_2, ScrcpyOptions3_3, ScrcpyOptions3_3_1, ScrcpyOptions3_3_2, ScrcpyOptionsLatest, ScrcpyOrientation, ScrcpyPointerId, ScrcpySetClipboardControlMessage, ScrcpySetDisplayPowerControlMessage, ScrcpyUHidCreateControlMessage, ScrcpyUHidOutputDeviceMessage, ScrcpyVideoCodecId, ScrcpyVideoCodecNameMap, ScrcpyVideoSizeImpl, clamp, isScrcpyOptionValue, omit, toScrcpyOptionValue) +} diff --git a/toolchain/side-effect-test/src/struct.js b/toolchain/side-effect-test/src/struct.js new file mode 100644 index 00000000..c076efd6 --- /dev/null +++ b/toolchain/side-effect-test/src/struct.js @@ -0,0 +1,39 @@ +import { + bipedal, + buffer, + concat, + decodeUtf8, + encodeUtf8, + extend, + s16, + s32, + s64, + s8, + string, + struct, + u16, + u32, + u64, + u8, +} from "@yume-chan/struct"; + +bipedal(function* () {}); +buffer(u8); +decodeUtf8(new Uint8Array()); +encodeUtf8(""); +s16(1); +s32(1); +s64(1); +s8(1); +string(1); +u16(1); +u32(1); +u64(1); +u8(1); +struct({}, { littleEndian: true }); +concat( + { littleEndian: true }, + struct({ a: u8 }, { littleEndian: true }), + struct({ b: u8 }, { littleEndian: true }), +); +extend(struct({ a: u16 }, { littleEndian: true }), { b: buffer(32) });