diff --git a/libraries/adb-credential-web/src/index.ts b/libraries/adb-credential-web/src/index.ts index 370b4787..5e099a50 100644 --- a/libraries/adb-credential-web/src/index.ts +++ b/libraries/adb-credential-web/src/index.ts @@ -68,7 +68,7 @@ async function getAllKeys() { * and stores them in IndexedDB. */ export default class AdbWebCredentialStore implements AdbCredentialStore { - #appName: string; + readonly #appName: string; constructor(appName = "Tango") { this.#appName = appName; diff --git a/libraries/adb-daemon-webusb/src/device.ts b/libraries/adb-daemon-webusb/src/device.ts index f4571731..6386ba48 100644 --- a/libraries/adb-daemon-webusb/src/device.ts +++ b/libraries/adb-daemon-webusb/src/device.ts @@ -54,27 +54,27 @@ export function mergeDefaultAdbInterfaceFilter( export class AdbDaemonWebUsbConnection implements ReadableWritablePair> { - #device: AdbDaemonWebUsbDevice; + readonly #device: AdbDaemonWebUsbDevice; get device() { return this.#device; } - #inEndpoint: USBEndpoint; + readonly #inEndpoint: USBEndpoint; get inEndpoint() { return this.#inEndpoint; } - #outEndpoint: USBEndpoint; + readonly #outEndpoint: USBEndpoint; get outEndpoint() { return this.#outEndpoint; } - #readable: ReadableStream; + readonly #readable: ReadableStream; get readable() { return this.#readable; } - #writable: WritableStream>; + readonly #writable: WritableStream>; get writable() { return this.#writable; } @@ -233,15 +233,15 @@ export class AdbDaemonWebUsbConnection export class AdbDaemonWebUsbDevice implements AdbDaemonDevice { static DeviceBusyError = _DeviceBusyError; - #interface: UsbInterfaceIdentifier; - #usbManager: USB; + readonly #interface: UsbInterfaceIdentifier; + readonly #usbManager: USB; - #raw: USBDevice; + readonly #raw: USBDevice; get raw() { return this.#raw; } - #serial: string; + readonly #serial: string; get serial(): string { return this.#serial; } diff --git a/libraries/adb-daemon-webusb/src/manager.ts b/libraries/adb-daemon-webusb/src/manager.ts index 525b57bf..3efb92da 100644 --- a/libraries/adb-daemon-webusb/src/manager.ts +++ b/libraries/adb-daemon-webusb/src/manager.ts @@ -23,7 +23,7 @@ export class AdbDaemonWebUsbDeviceManager { ? new AdbDaemonWebUsbDeviceManager(globalThis.navigator.usb) : undefined)(); - #usbManager: USB; + readonly #usbManager: USB; /** * Create a new instance of {@link AdbDaemonWebUsbDeviceManager} using the specified WebUSB implementation. diff --git a/libraries/adb/src/adb.ts b/libraries/adb/src/adb.ts index e58619e7..18eab4ba 100644 --- a/libraries/adb/src/adb.ts +++ b/libraries/adb/src/adb.ts @@ -9,10 +9,10 @@ import type { AdbBanner } from "./banner.js"; import type { AdbFrameBuffer } from "./commands/index.js"; import { AdbPower, - AdbReverseCommand, + AdbReverseService, AdbSubprocessService, AdbSync, - AdbTcpIpCommand, + AdbTcpIpService, escapeArg, framebuffer, } from "./commands/index.js"; @@ -61,26 +61,29 @@ export interface AdbTransport extends Closeable { } export class Adb implements Closeable { - readonly transport: AdbTransport; + readonly #transport: AdbTransport; + get transport(): AdbTransport { + return this.#transport; + } get serial() { - return this.transport.serial; + return this.#transport.serial; } get maxPayloadSize() { - return this.transport.maxPayloadSize; + return this.#transport.maxPayloadSize; } get banner() { - return this.transport.banner; + return this.#transport.banner; } get disconnected() { - return this.transport.disconnected; + return this.#transport.disconnected; } public get clientFeatures() { - return this.transport.clientFeatures; + return this.#transport.clientFeatures; } public get deviceFeatures() { @@ -89,16 +92,16 @@ export class Adb implements Closeable { readonly subprocess: AdbSubprocessService; readonly power: AdbPower; - readonly reverse: AdbReverseCommand; - readonly tcpip: AdbTcpIpCommand; + readonly reverse: AdbReverseService; + readonly tcpip: AdbTcpIpService; constructor(transport: AdbTransport) { - this.transport = transport; + this.#transport = transport; this.subprocess = new AdbSubprocessService(this); this.power = new AdbPower(this); - this.reverse = new AdbReverseCommand(this); - this.tcpip = new AdbTcpIpCommand(this); + this.reverse = new AdbReverseService(this); + this.tcpip = new AdbTcpIpService(this); } canUseFeature(feature: AdbFeature): boolean { @@ -112,7 +115,7 @@ export class Adb implements Closeable { * Creates a new ADB Socket to the specified service or socket address. */ async createSocket(service: string): Promise { - return this.transport.connect(service); + return this.#transport.connect(service); } async createSocketAndWait(service: string): Promise { @@ -162,6 +165,6 @@ export class Adb implements Closeable { } async close(): Promise { - await this.transport.close(); + await this.#transport.close(); } } diff --git a/libraries/adb/src/banner.ts b/libraries/adb/src/banner.ts index 5415b073..faf87335 100644 --- a/libraries/adb/src/banner.ts +++ b/libraries/adb/src/banner.ts @@ -51,22 +51,22 @@ export class AdbBanner { return new AdbBanner(product, model, device, features); } - #product: string | undefined; + readonly #product: string | undefined; get product() { return this.#product; } - #model: string | undefined; + readonly #model: string | undefined; get model() { return this.#model; } - #device: string | undefined; + readonly #device: string | undefined; get device() { return this.#device; } - #features: AdbFeature[] = []; + readonly #features: AdbFeature[] = []; get features() { return this.#features; } diff --git a/libraries/adb/src/commands/base.ts b/libraries/adb/src/commands/base.ts index 617ddc00..2be75da2 100644 --- a/libraries/adb/src/commands/base.ts +++ b/libraries/adb/src/commands/base.ts @@ -3,7 +3,7 @@ import { AutoDisposable } from "@yume-chan/event"; import type { Adb } from "../adb.js"; export class AdbServiceBase extends AutoDisposable { - #adb: Adb; + readonly #adb: Adb; get adb() { return this.#adb; } diff --git a/libraries/adb/src/commands/reverse.ts b/libraries/adb/src/commands/reverse.ts index f3c1a8f9..7e468c19 100644 --- a/libraries/adb/src/commands/reverse.ts +++ b/libraries/adb/src/commands/reverse.ts @@ -9,9 +9,11 @@ import { struct, } from "@yume-chan/struct"; -import type { Adb, AdbIncomingSocketHandler } from "../adb.js"; +import type { AdbIncomingSocketHandler } from "../adb.js"; import { hexToNumber, sequenceEqual } from "../utils/index.js"; +import { AdbServiceBase } from "./base.js"; + export interface AdbForwardListener { deviceSerial: string; @@ -82,15 +84,9 @@ function decimalToNumber(buffer: Uint8Array) { const OKAY = encodeUtf8("OKAY"); -export class AdbReverseCommand { - protected adb: Adb; - +export class AdbReverseService extends AdbServiceBase { readonly #deviceAddressToLocalAddress = new Map(); - constructor(adb: Adb) { - this.adb = adb; - } - protected async createBufferedStream(service: string) { const socket = await this.adb.createSocket(service); return new BufferedReadableStream(socket.readable); diff --git a/libraries/adb/src/commands/subprocess/service.ts b/libraries/adb/src/commands/subprocess/service.ts index dabd101e..725d11de 100644 --- a/libraries/adb/src/commands/subprocess/service.ts +++ b/libraries/adb/src/commands/subprocess/service.ts @@ -5,17 +5,17 @@ import { AdbNoneProtocolSubprocessService } from "./none/index.js"; import { AdbShellProtocolSubprocessService } from "./shell/index.js"; export class AdbSubprocessService { - #adb: Adb; + readonly #adb: Adb; get adb() { return this.#adb; } - #noneProtocol: AdbNoneProtocolSubprocessService; + readonly #noneProtocol: AdbNoneProtocolSubprocessService; get noneProtocol(): AdbNoneProtocolSubprocessService { return this.#noneProtocol; } - #shellProtocol?: AdbShellProtocolSubprocessService; + readonly #shellProtocol?: AdbShellProtocolSubprocessService; get shellProtocol(): AdbShellProtocolSubprocessService | undefined { return this.#shellProtocol; } diff --git a/libraries/adb/src/commands/sync/pull.ts b/libraries/adb/src/commands/sync/pull.ts index 95bd1168..df937288 100644 --- a/libraries/adb/src/commands/sync/pull.ts +++ b/libraries/adb/src/commands/sync/pull.ts @@ -1,5 +1,4 @@ -import type { ReadableStream } from "@yume-chan/stream-extra"; -import { PushReadableStream } from "@yume-chan/stream-extra"; +import { ReadableStream } from "@yume-chan/stream-extra"; import type { StructValue } from "@yume-chan/struct"; import { buffer, struct, u32 } from "@yume-chan/struct"; @@ -52,10 +51,5 @@ export function adbSyncPull( socket: AdbSyncSocket, path: string, ): ReadableStream { - // TODO: use `ReadableStream.from` when it's supported - return new PushReadableStream(async (controller) => { - for await (const data of adbSyncPullGenerator(socket, path)) { - await controller.enqueue(data); - } - }); + return ReadableStream.from(adbSyncPullGenerator(socket, path)); } diff --git a/libraries/adb/src/commands/sync/response.ts b/libraries/adb/src/commands/sync/response.ts index 1bad8d60..2fa72daf 100644 --- a/libraries/adb/src/commands/sync/response.ts +++ b/libraries/adb/src/commands/sync/response.ts @@ -2,6 +2,8 @@ import { getUint32LittleEndian } from "@yume-chan/no-data-view"; import type { AsyncExactReadable, StructDeserializer } from "@yume-chan/struct"; import { decodeUtf8, string, struct, u32 } from "@yume-chan/struct"; +import { unreachable } from "../../utils/no-op.js"; + function encodeAsciiUnchecked(value: string): Uint8Array { const result = new Uint8Array(value.length); for (let i = 0; i < value.length; i += 1) { @@ -83,7 +85,7 @@ export async function* adbSyncReadResponses( switch (getUint32LittleEndian(buffer, 0)) { case AdbSyncResponseId.Fail: await AdbSyncFailResponse.deserialize(stream); - throw new Error("Unreachable"); + unreachable(); case AdbSyncResponseId.Done: // `DONE` responses' size are always same as the request's normal response. // diff --git a/libraries/adb/src/commands/tcpip.ts b/libraries/adb/src/commands/tcpip.ts index 7b5a2f8c..3056ca3d 100644 --- a/libraries/adb/src/commands/tcpip.ts +++ b/libraries/adb/src/commands/tcpip.ts @@ -27,7 +27,7 @@ function parsePort(value: string): number | undefined { return Number.parseInt(value, 10); } -export class AdbTcpIpCommand extends AdbServiceBase { +export class AdbTcpIpService extends AdbServiceBase { async getListenAddresses(): Promise { const serviceListenAddresses = await this.adb.getProp( "service.adb.listen_addrs", diff --git a/libraries/adb/src/daemon/dispatcher.ts b/libraries/adb/src/daemon/dispatcher.ts index 3b9acf18..67536c31 100644 --- a/libraries/adb/src/daemon/dispatcher.ts +++ b/libraries/adb/src/daemon/dispatcher.ts @@ -101,18 +101,21 @@ export class AdbPacketDispatcher implements Closeable { */ readonly #sockets = new Map(); - #writer: WritableStreamDefaultWriter>; + readonly #writer: WritableStreamDefaultWriter>; readonly options: AdbPacketDispatcherOptions; #closed = false; - #disconnected = new PromiseResolver(); + readonly #disconnected = new PromiseResolver(); get disconnected() { return this.#disconnected.promise; } - #incomingSocketHandlers = new Map(); - #readAbortController = new AbortController(); + readonly #incomingSocketHandlers = new Map< + string, + AdbIncomingSocketHandler + >(); + readonly #readAbortController = new AbortController(); constructor( connection: ReadableWritablePair< diff --git a/libraries/adb/src/daemon/socket.ts b/libraries/adb/src/daemon/socket.ts index c6eff004..e24e2098 100644 --- a/libraries/adb/src/daemon/socket.ts +++ b/libraries/adb/src/daemon/socket.ts @@ -43,7 +43,7 @@ export class AdbDaemonSocketController readonly localCreated!: boolean; readonly service!: string; - #readable: ReadableStream; + readonly #readable: ReadableStream; #readableController!: PushReadableStreamController; get readable() { return this.#readable; @@ -54,12 +54,12 @@ export class AdbDaemonSocketController #closed = false; - #closedPromise = new PromiseResolver(); + readonly #closedPromise = new PromiseResolver(); get closed() { return this.#closedPromise.promise; } - #socket: AdbDaemonSocket; + readonly #socket: AdbDaemonSocket; get socket() { return this.#socket; } @@ -178,7 +178,7 @@ export class AdbDaemonSocketController * A duplex stream representing a socket to ADB daemon. */ export class AdbDaemonSocket implements AdbDaemonSocketInfo, AdbSocket { - #controller: AdbDaemonSocketController; + readonly #controller: AdbDaemonSocketController; get localId(): number { return this.#controller.localId; diff --git a/libraries/adb/src/server/client.ts b/libraries/adb/src/server/client.ts index a3d56c97..b6bc0eac 100644 --- a/libraries/adb/src/server/client.ts +++ b/libraries/adb/src/server/client.ts @@ -112,7 +112,7 @@ export class AdbServerClient { readonly wireless = new WirelessCommands(this); readonly mDns = new MDnsCommands(this); - #observerOwner = new AdbServerDeviceObserverOwner(this); + readonly #observerOwner = new AdbServerDeviceObserverOwner(this); constructor(connector: AdbServerClient.ServerConnector) { this.connector = connector; diff --git a/libraries/adb/src/server/commands/m-dns.ts b/libraries/adb/src/server/commands/m-dns.ts index 7c1255a7..394b120a 100644 --- a/libraries/adb/src/server/commands/m-dns.ts +++ b/libraries/adb/src/server/commands/m-dns.ts @@ -3,7 +3,7 @@ import type { AdbServerClient } from "../client.js"; export class MDnsCommands { - #client: AdbServerClient; + readonly #client: AdbServerClient; constructor(client: AdbServerClient) { this.#client = client; diff --git a/libraries/adb/src/server/commands/wireless.ts b/libraries/adb/src/server/commands/wireless.ts index 773146b8..d8118e0e 100644 --- a/libraries/adb/src/server/commands/wireless.ts +++ b/libraries/adb/src/server/commands/wireless.ts @@ -26,7 +26,7 @@ export class AlreadyConnectedError extends Error { } export class WirelessCommands { - #client: AdbServerClient; + readonly #client: AdbServerClient; constructor(client: AdbServerClient) { this.#client = client; diff --git a/libraries/struct/src/field/factory.ts b/libraries/struct/src/field/factory.ts index 1edd5c61..c50a60ee 100644 --- a/libraries/struct/src/field/factory.ts +++ b/libraries/struct/src/field/factory.ts @@ -9,7 +9,7 @@ import type { import { byobFieldSerializer, defaultFieldSerializer } from "./serialize.js"; import type { Field, FieldDeserializeContext, FieldOptions } from "./types.js"; -export type MaybeBipedalFieldDeserializer = BipedalGenerator< +export type BipedalFieldDeserializer = BipedalGenerator< undefined, T, [reader: AsyncExactReadable, context: FieldDeserializeContext] @@ -20,7 +20,7 @@ function _field( size: number, type: "default", serialize: DefaultFieldSerializer, - deserialize: MaybeBipedalFieldDeserializer, + deserialize: BipedalFieldDeserializer, options?: FieldOptions, ): Field; // eslint-disable-next-line @typescript-eslint/max-params @@ -28,7 +28,7 @@ function _field( size: number, type: "byob", serialize: ByobFieldSerializer, - deserialize: MaybeBipedalFieldDeserializer, + deserialize: BipedalFieldDeserializer, options?: FieldOptions, ): Field; /* #__NO_SIDE_EFFECTS__ */ @@ -37,7 +37,7 @@ function _field( size: number, type: "default" | "byob", serialize: DefaultFieldSerializer | ByobFieldSerializer, - deserialize: MaybeBipedalFieldDeserializer, + deserialize: BipedalFieldDeserializer, options?: FieldOptions, ): Field { const field: Field = { diff --git a/toolchain/eslint-config/eslint.config.js b/toolchain/eslint-config/eslint.config.js index fbd8c926..1d2fd429 100644 --- a/toolchain/eslint-config/eslint.config.js +++ b/toolchain/eslint-config/eslint.config.js @@ -25,6 +25,7 @@ export default tslint.config( maxBOF: 0, }, ], + "no-fallthrough": "off", }, }, ...tslint.configs.recommendedTypeChecked,