mirror of
https://github.com/yume-chan/ya-webadb.git
synced 2025-10-03 09:49:24 +02:00
refactor: remove side effects
This commit is contained in:
parent
a335c1495c
commit
92511c63de
12 changed files with 241 additions and 194 deletions
|
@ -22,6 +22,7 @@ import {
|
||||||
import type { ExactReadable } from "@yume-chan/struct";
|
import type { ExactReadable } from "@yume-chan/struct";
|
||||||
import { EmptyUint8Array } from "@yume-chan/struct";
|
import { EmptyUint8Array } from "@yume-chan/struct";
|
||||||
|
|
||||||
|
import { DeviceBusyError as _DeviceBusyError } from "./error.js";
|
||||||
import type { UsbInterfaceFilter, UsbInterfaceIdentifier } from "./utils.js";
|
import type { UsbInterfaceFilter, UsbInterfaceIdentifier } from "./utils.js";
|
||||||
import { findUsbEndpoints, getSerialNumber, isErrorName } from "./utils.js";
|
import { findUsbEndpoints, getSerialNumber, isErrorName } from "./utils.js";
|
||||||
|
|
||||||
|
@ -254,6 +255,8 @@ export class AdbDaemonWebUsbConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
||||||
|
static DeviceBusyError = _DeviceBusyError;
|
||||||
|
|
||||||
#interface: UsbInterfaceIdentifier;
|
#interface: UsbInterfaceIdentifier;
|
||||||
#usbManager: USB;
|
#usbManager: USB;
|
||||||
|
|
||||||
|
@ -348,11 +351,5 @@ export class AdbDaemonWebUsbDevice implements AdbDaemonDevice {
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace AdbDaemonWebUsbDevice {
|
export namespace AdbDaemonWebUsbDevice {
|
||||||
export class DeviceBusyError extends Error {
|
export type DeviceBusyError = _DeviceBusyError;
|
||||||
constructor(cause?: Error) {
|
|
||||||
super("The device is already in used by another program", {
|
|
||||||
cause,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
7
libraries/adb-daemon-webusb/src/error.ts
Normal file
7
libraries/adb-daemon-webusb/src/error.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export class DeviceBusyError extends Error {
|
||||||
|
constructor(cause?: Error) {
|
||||||
|
super("The device is already in used by another program", {
|
||||||
|
cause,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,11 +18,11 @@ export class AdbDaemonWebUsbDeviceManager {
|
||||||
*
|
*
|
||||||
* May be `undefined` if current runtime does not support WebUSB.
|
* May be `undefined` if current runtime does not support WebUSB.
|
||||||
*/
|
*/
|
||||||
static readonly BROWSER =
|
static readonly BROWSER = /* #__PURE__ */ (() => {
|
||||||
typeof globalThis.navigator !== "undefined" &&
|
typeof globalThis.navigator !== "undefined" && globalThis.navigator.usb
|
||||||
!!globalThis.navigator.usb
|
|
||||||
? new AdbDaemonWebUsbDeviceManager(globalThis.navigator.usb)
|
? new AdbDaemonWebUsbDeviceManager(globalThis.navigator.usb)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
})();
|
||||||
|
|
||||||
#usbManager: USB;
|
#usbManager: USB;
|
||||||
|
|
||||||
|
|
|
@ -15,16 +15,27 @@ import type { AdbIncomingSocketHandler, AdbSocket, Closeable } from "../adb.js";
|
||||||
import { AdbBanner } from "../banner.js";
|
import { AdbBanner } from "../banner.js";
|
||||||
import type { DeviceObserver as DeviceObserverBase } from "../device-observer.js";
|
import type { DeviceObserver as DeviceObserverBase } from "../device-observer.js";
|
||||||
import type { AdbFeature } from "../features.js";
|
import type { AdbFeature } from "../features.js";
|
||||||
import { hexToNumber, sequenceEqual } from "../utils/index.js";
|
import { hexToNumber } from "../utils/index.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
MDnsCommands,
|
||||||
|
WirelessCommands,
|
||||||
|
AlreadyConnectedError as _AlreadyConnectedError,
|
||||||
|
NetworkError as _NetworkError,
|
||||||
|
UnauthorizedError as _UnauthorizedError,
|
||||||
|
} from "./commands/index.js";
|
||||||
import { AdbServerDeviceObserverOwner } from "./observer.js";
|
import { AdbServerDeviceObserverOwner } from "./observer.js";
|
||||||
import { AdbServerStream, FAIL } from "./stream.js";
|
import { AdbServerStream } from "./stream.js";
|
||||||
import { AdbServerTransport } from "./transport.js";
|
import { AdbServerTransport } from "./transport.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client for the ADB Server.
|
* Client for the ADB Server.
|
||||||
*/
|
*/
|
||||||
export class AdbServerClient {
|
export class AdbServerClient {
|
||||||
|
static NetworkError = _NetworkError;
|
||||||
|
static UnauthorizedError = _UnauthorizedError;
|
||||||
|
static AlreadyConnectedError = _AlreadyConnectedError;
|
||||||
|
|
||||||
static parseDeviceList(value: string): AdbServerClient.Device[] {
|
static parseDeviceList(value: string): AdbServerClient.Device[] {
|
||||||
const devices: AdbServerClient.Device[] = [];
|
const devices: AdbServerClient.Device[] = [];
|
||||||
for (const line of value.split("\n")) {
|
for (const line of value.split("\n")) {
|
||||||
|
@ -99,8 +110,8 @@ export class AdbServerClient {
|
||||||
|
|
||||||
readonly connector: AdbServerClient.ServerConnector;
|
readonly connector: AdbServerClient.ServerConnector;
|
||||||
|
|
||||||
readonly wireless = new AdbServerClient.WirelessCommands(this);
|
readonly wireless = new WirelessCommands(this);
|
||||||
readonly mDns = new AdbServerClient.MDnsCommands(this);
|
readonly mDns = new MDnsCommands(this);
|
||||||
#observerOwner = new AdbServerDeviceObserverOwner(this);
|
#observerOwner = new AdbServerDeviceObserverOwner(this);
|
||||||
|
|
||||||
constructor(connector: AdbServerClient.ServerConnector) {
|
constructor(connector: AdbServerClient.ServerConnector) {
|
||||||
|
@ -537,138 +548,11 @@ export namespace AdbServerClient {
|
||||||
transportId: bigint;
|
transportId: bigint;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NetworkError extends Error {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message);
|
|
||||||
this.name = "NetworkError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class UnauthorizedError extends Error {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message);
|
|
||||||
this.name = "UnauthorizedError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AlreadyConnectedError extends Error {
|
|
||||||
constructor(message: string) {
|
|
||||||
super(message);
|
|
||||||
this.name = "AlreadyConnectedError";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WirelessCommands {
|
|
||||||
#client: AdbServerClient;
|
|
||||||
|
|
||||||
constructor(client: AdbServerClient) {
|
|
||||||
this.#client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `adb pair <password> <address>`
|
|
||||||
*/
|
|
||||||
async pair(address: string, password: string): Promise<void> {
|
|
||||||
const connection = await this.#client.createConnection(
|
|
||||||
`host:pair:${password}:${address}`,
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
const response = await connection.readExactly(4);
|
|
||||||
// `response` is either `FAIL`, or 4 hex digits for length of the string
|
|
||||||
if (sequenceEqual(response, FAIL)) {
|
|
||||||
throw new Error(await connection.readString());
|
|
||||||
}
|
|
||||||
const length = hexToNumber(response);
|
|
||||||
// Ignore the string as it's always `Successful ...`
|
|
||||||
await connection.readExactly(length);
|
|
||||||
} finally {
|
|
||||||
await connection.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `adb connect <address>`
|
|
||||||
*/
|
|
||||||
async connect(address: string): Promise<void> {
|
|
||||||
const connection = await this.#client.createConnection(
|
|
||||||
`host:connect:${address}`,
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
const response = await connection.readString();
|
|
||||||
switch (response) {
|
|
||||||
case `already connected to ${address}`:
|
|
||||||
throw new AdbServerClient.AlreadyConnectedError(
|
|
||||||
response,
|
|
||||||
);
|
|
||||||
case `failed to connect to ${address}`: // `adb pair` mode not authorized
|
|
||||||
case `failed to authenticate to ${address}`: // `adb tcpip` mode not authorized
|
|
||||||
throw new AdbServerClient.UnauthorizedError(response);
|
|
||||||
case `connected to ${address}`:
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
throw new AdbServerClient.NetworkError(response);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
await connection.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `adb disconnect <address>`
|
|
||||||
*/
|
|
||||||
async disconnect(address: string): Promise<void> {
|
|
||||||
const connection = await this.#client.createConnection(
|
|
||||||
`host:disconnect:${address}`,
|
|
||||||
);
|
|
||||||
try {
|
|
||||||
await connection.readString();
|
|
||||||
} finally {
|
|
||||||
await connection.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class MDnsCommands {
|
|
||||||
#client: AdbServerClient;
|
|
||||||
|
|
||||||
constructor(client: AdbServerClient) {
|
|
||||||
this.#client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
async check() {
|
|
||||||
const connection =
|
|
||||||
await this.#client.createConnection("host:mdns:check");
|
|
||||||
try {
|
|
||||||
const response = await connection.readString();
|
|
||||||
return !response.startsWith("ERROR:");
|
|
||||||
} finally {
|
|
||||||
await connection.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async getServices() {
|
|
||||||
const connection =
|
|
||||||
await this.#client.createConnection("host:mdns:services");
|
|
||||||
try {
|
|
||||||
const response = await connection.readString();
|
|
||||||
return response
|
|
||||||
.split("\n")
|
|
||||||
.filter(Boolean)
|
|
||||||
.map((line) => {
|
|
||||||
const parts = line.split("\t");
|
|
||||||
return {
|
|
||||||
name: parts[0]!,
|
|
||||||
service: parts[1]!,
|
|
||||||
address: parts[2]!,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
await connection.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeviceObserver extends DeviceObserverBase<Device> {
|
export interface DeviceObserver extends DeviceObserverBase<Device> {
|
||||||
onError: Event<Error>;
|
onError: Event<Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type NetworkError = _NetworkError;
|
||||||
|
export type UnauthorizedError = _UnauthorizedError;
|
||||||
|
export type AlreadyConnectedError = _AlreadyConnectedError;
|
||||||
}
|
}
|
||||||
|
|
2
libraries/adb/src/server/commands/index.ts
Normal file
2
libraries/adb/src/server/commands/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from "./m-dns.js";
|
||||||
|
export * from "./wireless.js";
|
43
libraries/adb/src/server/commands/m-dns.ts
Normal file
43
libraries/adb/src/server/commands/m-dns.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// cspell:ignore mdns
|
||||||
|
|
||||||
|
import type { AdbServerClient } from "../client.js";
|
||||||
|
|
||||||
|
export class MDnsCommands {
|
||||||
|
#client: AdbServerClient;
|
||||||
|
|
||||||
|
constructor(client: AdbServerClient) {
|
||||||
|
this.#client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
async check() {
|
||||||
|
const connection =
|
||||||
|
await this.#client.createConnection("host:mdns:check");
|
||||||
|
try {
|
||||||
|
const response = await connection.readString();
|
||||||
|
return !response.startsWith("ERROR:");
|
||||||
|
} finally {
|
||||||
|
await connection.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getServices() {
|
||||||
|
const connection =
|
||||||
|
await this.#client.createConnection("host:mdns:services");
|
||||||
|
try {
|
||||||
|
const response = await connection.readString();
|
||||||
|
return response
|
||||||
|
.split("\n")
|
||||||
|
.filter(Boolean)
|
||||||
|
.map((line) => {
|
||||||
|
const parts = line.split("\t");
|
||||||
|
return {
|
||||||
|
name: parts[0]!,
|
||||||
|
service: parts[1]!,
|
||||||
|
address: parts[2]!,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
await connection.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
95
libraries/adb/src/server/commands/wireless.ts
Normal file
95
libraries/adb/src/server/commands/wireless.ts
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// cspell:ignore tport
|
||||||
|
|
||||||
|
import { hexToNumber, sequenceEqual } from "../../utils/index.js";
|
||||||
|
import type { AdbServerClient } from "../client.js";
|
||||||
|
|
||||||
|
import { FAIL } from "../stream.js";
|
||||||
|
|
||||||
|
export class NetworkError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = "NetworkError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UnauthorizedError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = "UnauthorizedError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AlreadyConnectedError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super(message);
|
||||||
|
this.name = "AlreadyConnectedError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WirelessCommands {
|
||||||
|
#client: AdbServerClient;
|
||||||
|
|
||||||
|
constructor(client: AdbServerClient) {
|
||||||
|
this.#client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `adb pair <password> <address>`
|
||||||
|
*/
|
||||||
|
async pair(address: string, password: string): Promise<void> {
|
||||||
|
const connection = await this.#client.createConnection(
|
||||||
|
`host:pair:${password}:${address}`,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
const response = await connection.readExactly(4);
|
||||||
|
// `response` is either `FAIL`, or 4 hex digits for length of the string
|
||||||
|
if (sequenceEqual(response, FAIL)) {
|
||||||
|
throw new Error(await connection.readString());
|
||||||
|
}
|
||||||
|
const length = hexToNumber(response);
|
||||||
|
// Ignore the string as it's always `Successful ...`
|
||||||
|
await connection.readExactly(length);
|
||||||
|
} finally {
|
||||||
|
await connection.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `adb connect <address>`
|
||||||
|
*/
|
||||||
|
async connect(address: string): Promise<void> {
|
||||||
|
const connection = await this.#client.createConnection(
|
||||||
|
`host:connect:${address}`,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
const response = await connection.readString();
|
||||||
|
switch (response) {
|
||||||
|
case `already connected to ${address}`:
|
||||||
|
throw new AlreadyConnectedError(response);
|
||||||
|
case `failed to connect to ${address}`: // `adb pair` mode not authorized
|
||||||
|
case `failed to authenticate to ${address}`: // `adb tcpip` mode not authorized
|
||||||
|
throw new UnauthorizedError(response);
|
||||||
|
case `connected to ${address}`:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
throw new NetworkError(response);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await connection.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* `adb disconnect <address>`
|
||||||
|
*/
|
||||||
|
async disconnect(address: string): Promise<void> {
|
||||||
|
const connection = await this.#client.createConnection(
|
||||||
|
`host:disconnect:${address}`,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
await connection.readString();
|
||||||
|
} finally {
|
||||||
|
await connection.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,8 @@ import { AdbFeature } from "../features.js";
|
||||||
|
|
||||||
import type { AdbServerClient } from "./client.js";
|
import type { AdbServerClient } from "./client.js";
|
||||||
|
|
||||||
export const ADB_SERVER_DEFAULT_FEATURES = [
|
export const ADB_SERVER_DEFAULT_FEATURES = /* #__PURE__ */ (() =>
|
||||||
|
[
|
||||||
AdbFeature.ShellV2,
|
AdbFeature.ShellV2,
|
||||||
AdbFeature.Cmd,
|
AdbFeature.Cmd,
|
||||||
AdbFeature.StatV2,
|
AdbFeature.StatV2,
|
||||||
|
@ -29,7 +30,7 @@ export const ADB_SERVER_DEFAULT_FEATURES = [
|
||||||
"sendrecv_v2_lz4",
|
"sendrecv_v2_lz4",
|
||||||
"sendrecv_v2_zstd",
|
"sendrecv_v2_zstd",
|
||||||
"sendrecv_v2_dry_run_send",
|
"sendrecv_v2_dry_run_send",
|
||||||
] as AdbFeature[];
|
] as AdbFeature[])();
|
||||||
|
|
||||||
export class AdbServerTransport implements AdbTransport {
|
export class AdbServerTransport implements AdbTransport {
|
||||||
#client: AdbServerClient;
|
#client: AdbServerClient;
|
||||||
|
|
|
@ -6,11 +6,14 @@ import type { SingleUser } from "./utils.js";
|
||||||
|
|
||||||
export type SettingsNamespace = "system" | "secure" | "global";
|
export type SettingsNamespace = "system" | "secure" | "global";
|
||||||
|
|
||||||
export enum SettingsResetMode {
|
export const SettingsResetMode = {
|
||||||
UntrustedDefaults = "untrusted_defaults",
|
UntrustedDefaults: "untrusted_defaults",
|
||||||
UntrustedClear = "untrusted_clear",
|
UntrustedClear: "untrusted_clear",
|
||||||
TrustedDefaults = "trusted_defaults",
|
TrustedDefaults: "trusted_defaults",
|
||||||
}
|
} as const;
|
||||||
|
|
||||||
|
export type SettingsResetMode =
|
||||||
|
(typeof SettingsResetMode)[keyof typeof SettingsResetMode];
|
||||||
|
|
||||||
export interface SettingsOptions {
|
export interface SettingsOptions {
|
||||||
user?: SingleUser;
|
user?: SingleUser;
|
||||||
|
|
|
@ -42,14 +42,16 @@ export interface BufferLike {
|
||||||
|
|
||||||
export const EmptyUint8Array = new Uint8Array(0);
|
export const EmptyUint8Array = new Uint8Array(0);
|
||||||
|
|
||||||
export const buffer: BufferLike = function (
|
// Prettier will move the annotation and make it invalid
|
||||||
|
// prettier-ignore
|
||||||
|
export const buffer: BufferLike = (/* #__NO_SIDE_EFFECTS__ */ (
|
||||||
lengthOrField:
|
lengthOrField:
|
||||||
| string
|
| string
|
||||||
| number
|
| number
|
||||||
| Field<number, never, unknown>
|
| Field<number, never, unknown>
|
||||||
| BufferLengthConverter<string, unknown>,
|
| BufferLengthConverter<string, unknown>,
|
||||||
converter?: Converter<Uint8Array, unknown>,
|
converter?: Converter<Uint8Array, unknown>,
|
||||||
): Field<unknown, string, Record<string, unknown>> {
|
): Field<unknown, string, Record<string, unknown>> => {
|
||||||
if (typeof lengthOrField === "number") {
|
if (typeof lengthOrField === "number") {
|
||||||
if (converter) {
|
if (converter) {
|
||||||
if (lengthOrField === 0) {
|
if (lengthOrField === 0) {
|
||||||
|
@ -257,4 +259,4 @@ export const buffer: BufferLike = function (
|
||||||
return reader.readExactly(length);
|
return reader.readExactly(length);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} as never;
|
}) as never;
|
||||||
|
|
|
@ -23,18 +23,19 @@ export interface NumberField<T> extends Field<T, never, never> {
|
||||||
|
|
||||||
/* #__NO_SIDE_EFFECTS__ */
|
/* #__NO_SIDE_EFFECTS__ */
|
||||||
function factory<T>(
|
function factory<T>(
|
||||||
|
fn: NumberField<T>,
|
||||||
size: number,
|
size: number,
|
||||||
serialize: Field<T, never, never>["serialize"],
|
serialize: Field<T, never, never>["serialize"],
|
||||||
deserialize: Field<T, never, never>["deserialize"],
|
deserialize: Field<T, never, never>["deserialize"],
|
||||||
): NumberField<T> {
|
) {
|
||||||
const result = () => result;
|
fn.size = size;
|
||||||
result.size = size;
|
fn.serialize = serialize;
|
||||||
result.serialize = serialize;
|
fn.deserialize = deserialize;
|
||||||
result.deserialize = deserialize;
|
|
||||||
return result as never;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const u8 = factory<number>(
|
export const u8: NumberField<number> = (() => u8) as never;
|
||||||
|
factory(
|
||||||
|
u8,
|
||||||
1,
|
1,
|
||||||
(value, { buffer, index }) => {
|
(value, { buffer, index }) => {
|
||||||
buffer[index] = value;
|
buffer[index] = value;
|
||||||
|
@ -45,7 +46,9 @@ export const u8 = factory<number>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const s8 = factory<number>(
|
export const s8: NumberField<number> = (() => s8) as never;
|
||||||
|
factory(
|
||||||
|
s8,
|
||||||
1,
|
1,
|
||||||
(value, { buffer, index }) => {
|
(value, { buffer, index }) => {
|
||||||
buffer[index] = value;
|
buffer[index] = value;
|
||||||
|
@ -56,7 +59,9 @@ export const s8 = factory<number>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const u16 = factory<number>(
|
export const u16: NumberField<number> = (() => u16) as never;
|
||||||
|
factory(
|
||||||
|
u16,
|
||||||
2,
|
2,
|
||||||
(value, { buffer, index, littleEndian }) => {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
setUint16(buffer, index, value, littleEndian);
|
setUint16(buffer, index, value, littleEndian);
|
||||||
|
@ -67,7 +72,9 @@ export const u16 = factory<number>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const s16 = factory<number>(
|
export const s16: NumberField<number> = (() => u16) as never;
|
||||||
|
factory(
|
||||||
|
s16,
|
||||||
2,
|
2,
|
||||||
(value, { buffer, index, littleEndian }) => {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
setInt16(buffer, index, value, littleEndian);
|
setInt16(buffer, index, value, littleEndian);
|
||||||
|
@ -78,7 +85,9 @@ export const s16 = factory<number>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const u32 = factory<number>(
|
export const u32: NumberField<number> = (() => u32) as never;
|
||||||
|
factory(
|
||||||
|
u32,
|
||||||
4,
|
4,
|
||||||
(value, { buffer, index, littleEndian }) => {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
setUint32(buffer, index, value, littleEndian);
|
setUint32(buffer, index, value, littleEndian);
|
||||||
|
@ -89,7 +98,9 @@ export const u32 = factory<number>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const s32 = factory<number>(
|
export const s32: NumberField<number> = (() => s32) as never;
|
||||||
|
factory(
|
||||||
|
s32,
|
||||||
4,
|
4,
|
||||||
(value, { buffer, index, littleEndian }) => {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
setInt32(buffer, index, value, littleEndian);
|
setInt32(buffer, index, value, littleEndian);
|
||||||
|
@ -100,7 +111,9 @@ export const s32 = factory<number>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const u64 = factory<bigint>(
|
export const u64: NumberField<bigint> = (() => u64) as never;
|
||||||
|
factory(
|
||||||
|
u64,
|
||||||
8,
|
8,
|
||||||
(value, { buffer, index, littleEndian }) => {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
setUint64(buffer, index, value, littleEndian);
|
setUint64(buffer, index, value, littleEndian);
|
||||||
|
@ -111,7 +124,9 @@ export const u64 = factory<bigint>(
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const s64 = factory<bigint>(
|
export const s64: NumberField<bigint> = (() => u64) as never;
|
||||||
|
factory(
|
||||||
|
s64,
|
||||||
8,
|
8,
|
||||||
(value, { buffer, index, littleEndian }) => {
|
(value, { buffer, index, littleEndian }) => {
|
||||||
setInt64(buffer, index, value, littleEndian);
|
setInt64(buffer, index, value, littleEndian);
|
||||||
|
|
|
@ -25,19 +25,17 @@ export interface String {
|
||||||
): Field<string, KOmitInit, KS>;
|
): Field<string, KOmitInit, KS>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rollup doesn't support `/* #__NO_SIDE_EFFECTS__ */ export const a = () => {}
|
// Prettier will move the annotation and make it invalid
|
||||||
/* #__NO_SIDE_EFFECTS__ */
|
// prettier-ignore
|
||||||
function _string(
|
export const string: String = (/* #__NO_SIDE_EFFECTS__ */ (
|
||||||
lengthOrField: string | number | BufferLengthConverter<string, unknown>,
|
lengthOrField: string | number | BufferLengthConverter<string, unknown>,
|
||||||
): Field<string, string, Record<string, unknown>> & {
|
): Field<string, string, Record<string, unknown>> & {
|
||||||
as: <T>(infer: T) => Field<T, string, Record<string, unknown>>;
|
as: <T>(infer: T) => Field<T, string, Record<string, unknown>>;
|
||||||
} {
|
} => {
|
||||||
const field = buffer(lengthOrField as never, {
|
const field = buffer(lengthOrField as never, {
|
||||||
convert: decodeUtf8,
|
convert: decodeUtf8,
|
||||||
back: encodeUtf8,
|
back: encodeUtf8,
|
||||||
});
|
});
|
||||||
(field as never as { as: unknown }).as = () => field;
|
(field as never as { as: unknown }).as = () => field;
|
||||||
return field as never;
|
return field as never;
|
||||||
}
|
}) as never;
|
||||||
|
|
||||||
export const string: String = _string as never;
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue