@v5x/serial 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -6
- package/dist/Vex.d.ts +4 -4
- package/dist/VexCRC.d.ts +0 -1
- package/dist/VexConnection.d.ts +81 -23
- package/dist/VexDevice.d.ts +41 -155
- package/{dts/VexDevice.d.ts → dist/VexDeviceState.d.ts} +63 -55
- package/dist/VexError.d.ts +47 -0
- package/dist/VexFirmware.d.ts +45 -0
- package/dist/VexIniConfig.d.ts +1 -1
- package/dist/VexPacket.d.ts +3 -512
- package/dist/VexPacketBase.d.ts +21 -0
- package/dist/VexPacketEncoder.d.ts +55 -0
- package/{dts/VexPacket.d.ts → dist/VexPacketModels.d.ts} +3 -107
- package/dist/VexPacketView.d.ts +3 -3
- package/dist/VexTransfers.d.ts +20 -0
- package/dist/index.cjs +4541 -0
- package/dist/index.cjs.map +25 -0
- package/dist/index.d.ts +9 -9
- package/dist/index.js +4460 -0
- package/dist/index.js.map +25 -0
- package/package.json +39 -71
- package/dist/v5-serial-protocol.cjs.js +0 -4516
- package/dist/v5-serial-protocol.cjs.js.map +0 -1
- package/dist/v5-serial-protocol.es.js +0 -4401
- package/dist/v5-serial-protocol.es.js.map +0 -1
- package/dts/Vex.d.ts +0 -235
- package/dts/Vex.js +0 -189
- package/dts/Vex.js.map +0 -1
- package/dts/VexCRC.d.ts +0 -19
- package/dts/VexCRC.js +0 -89
- package/dts/VexCRC.js.map +0 -1
- package/dts/VexConnection.d.ts +0 -45
- package/dts/VexConnection.js +0 -500
- package/dts/VexConnection.js.map +0 -1
- package/dts/VexDevice.js +0 -944
- package/dts/VexDevice.js.map +0 -1
- package/dts/VexEvent.d.ts +0 -16
- package/dts/VexEvent.js +0 -47
- package/dts/VexEvent.js.map +0 -1
- package/dts/VexFirmwareVersion.d.ts +0 -55
- package/dts/VexFirmwareVersion.js +0 -104
- package/dts/VexFirmwareVersion.js.map +0 -1
- package/dts/VexIniConfig.d.ts +0 -27
- package/dts/VexIniConfig.js +0 -122
- package/dts/VexIniConfig.js.map +0 -1
- package/dts/VexPacket.js +0 -1036
- package/dts/VexPacket.js.map +0 -1
- package/dts/VexPacketView.d.ts +0 -18
- package/dts/VexPacketView.js +0 -84
- package/dts/VexPacketView.js.map +0 -1
- package/dts/index.d.ts +0 -9
- package/dts/index.js +0 -10
- package/dts/index.js.map +0 -1
- package/index.d.ts +0 -1098
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
TypeScript implementation of the VEX V5 serial protocol.
|
|
4
4
|
|
|
5
|
+
See the [serial library documentation](https://docs.v5x.dev/serial/overview) for browser setup, guides, and high-level API reference.
|
|
6
|
+
|
|
5
7
|
This package provides helpers for connecting to V5 devices over the Web Serial
|
|
6
8
|
API, reading device state, transferring files, and working with protocol
|
|
7
9
|
packets.
|
|
@@ -14,16 +16,27 @@ bun add @v5x/serial
|
|
|
14
16
|
|
|
15
17
|
## Usage
|
|
16
18
|
|
|
19
|
+
Every public async API returns a `neverthrow` `ResultAsync` whose error channel
|
|
20
|
+
is a `VexSerialError`. Inspect the result with `.isOk()` / `.isErr()` or
|
|
21
|
+
`.match()` instead of using `try`/`catch`:
|
|
22
|
+
|
|
17
23
|
```ts
|
|
18
24
|
import { V5SerialConnection } from "@v5x/serial";
|
|
19
25
|
|
|
20
26
|
const connection = new V5SerialConnection(navigator.serial);
|
|
21
27
|
|
|
22
|
-
const
|
|
28
|
+
const opened = await connection.open();
|
|
29
|
+
if (opened.isErr()) {
|
|
30
|
+
console.error(opened.error); // VexSerialError with a stable .kind
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// opened.value: true | false | undefined (opened / busy / no port selected)
|
|
23
34
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
console.log(status);
|
|
35
|
+
const status = await connection.getSystemStatus();
|
|
36
|
+
if (status.isOk()) {
|
|
37
|
+
console.log(status.value);
|
|
38
|
+
} else {
|
|
39
|
+
console.error(status.error.kind, status.error.message);
|
|
27
40
|
}
|
|
28
41
|
```
|
|
29
42
|
|
|
@@ -31,20 +44,73 @@ Web Serial is browser-only and requires a secure context, such as HTTPS or
|
|
|
31
44
|
`localhost`. The user must grant access to a serial device before the connection
|
|
32
45
|
can open.
|
|
33
46
|
|
|
47
|
+
The package ships ESM, CommonJS, and TypeScript declarations. Packet and version
|
|
48
|
+
utilities work in Bun or Node.js, but direct browser device connections require
|
|
49
|
+
the Web Serial API. The `@v5x/cli` package is separate and currently supports
|
|
50
|
+
Linux only.
|
|
51
|
+
|
|
34
52
|
## Common Exports
|
|
35
53
|
|
|
36
54
|
- `V5SerialConnection` for opening and managing a serial connection.
|
|
37
55
|
- `V5SerialDevice` for higher-level device operations.
|
|
56
|
+
- `VexSerialError` and its subclasses (`VexNotConnectedError`,
|
|
57
|
+
`VexProtocolError`, `VexTransferError`, `VexDownloadError`,
|
|
58
|
+
`VexFirmwareError`, `VexIoError`, `VexInvalidArgumentError`) for typed failure
|
|
59
|
+
handling. Each carries a stable `kind` discriminator.
|
|
38
60
|
- `PacketEncoder`, `DeviceBoundPacket`, and `HostBoundPacket` for low-level
|
|
39
61
|
protocol work.
|
|
40
62
|
- `ProgramIniConfig` for creating VEX program metadata.
|
|
41
63
|
- Protocol enums and types from `Vex.ts`.
|
|
42
64
|
|
|
65
|
+
## Result-returning async APIs
|
|
66
|
+
|
|
67
|
+
All public async methods return `ResultAsync<T, VexSerialError>` (or
|
|
68
|
+
`ResultAsync<T, VexSerialError>`-yielding helpers) so failures are explicit in
|
|
69
|
+
the type system rather than thrown. State-changing operations are awaitable and
|
|
70
|
+
report errors through the result channel:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const r = await device.setMatchMode("disabled");
|
|
74
|
+
if (r.isErr()) console.error(r.error);
|
|
75
|
+
|
|
76
|
+
await device.brain.setActiveProgram(1).mapErr((e) => console.error(e));
|
|
77
|
+
await device.brain.setActiveProgram(0);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The former `device.matchMode = value` and
|
|
81
|
+
`device.brain.activeProgram = value` setters were fire-and-forget and have been
|
|
82
|
+
removed. Migrate to the corresponding `setMatchMode()` / `setActiveProgram()`
|
|
83
|
+
methods and handle the returned `Result`.
|
|
84
|
+
|
|
85
|
+
Legacy methods that resolved to `false`, `null`, or `undefined` on failure now
|
|
86
|
+
return a typed `Err` instead, preserving the prior success value semantics on
|
|
87
|
+
the `Ok` channel (e.g. `open()` still resolves to `Ok(true | false |
|
|
88
|
+
undefined)`).
|
|
89
|
+
|
|
90
|
+
## Transfers and timeouts
|
|
91
|
+
|
|
92
|
+
Bulk uploads and downloads on one `V5SerialConnection` are queued and run one at
|
|
93
|
+
a time. Await each high-level transfer; do not interleave manual low-level file
|
|
94
|
+
packets. A `V5SerialDevice` pauses its background refresh while a high-level
|
|
95
|
+
transfer is active by default.
|
|
96
|
+
|
|
97
|
+
Protocol requests default to a 1,000 ms response timeout. Individual transfer
|
|
98
|
+
phases use longer timeouts where erase, write, or exit operations need them.
|
|
99
|
+
`reconnect(0)` waits indefinitely, while a positive reconnect timeout is a total
|
|
100
|
+
deadline in milliseconds. A timeout or NACK is reported as a `VexProtocolError`
|
|
101
|
+
(or a related `VexSerialError` subclass) through the `Result` error channel; it
|
|
102
|
+
does not cancel work already running on the device.
|
|
103
|
+
|
|
104
|
+
User QSPI files are limited to `USER_FLASH_MAX_FILE_SIZE` (2 MiB). Firmware
|
|
105
|
+
updates download an archive containing non-empty `BOOT.bin` and `assets.bin`
|
|
106
|
+
images whose sizes must match the archive metadata. Firmware writes can render a
|
|
107
|
+
device unusable if power or communication is interrupted; keep them out of
|
|
108
|
+
normal application flows and validate the target VEXos version first.
|
|
109
|
+
|
|
43
110
|
## Build
|
|
44
111
|
|
|
45
112
|
```sh
|
|
46
113
|
bun run build
|
|
47
114
|
```
|
|
48
115
|
|
|
49
|
-
The build emits JavaScript bundles
|
|
50
|
-
`dts/` and `index.d.ts`.
|
|
116
|
+
The build emits JavaScript bundles and TypeScript declarations under `dist/`.
|
package/dist/Vex.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type VexFirmwareVersion } from "./VexFirmwareVersion";
|
|
2
|
-
import { type HostBoundPacket } from "./VexPacket";
|
|
1
|
+
import { type VexFirmwareVersion } from "./VexFirmwareVersion.js";
|
|
2
|
+
import { type HostBoundPacket } from "./VexPacket.js";
|
|
3
3
|
export declare const USER_PROG_CHUNK_SIZE = 4096;
|
|
4
4
|
export declare const USER_FLASH_START = 50331648;
|
|
5
5
|
export declare const USER_FLASH_SYS_CODE_START = 54525952;
|
|
@@ -86,8 +86,8 @@ export declare enum FileDownloadTarget {
|
|
|
86
86
|
FILE_TARGET_VBUF = 3,
|
|
87
87
|
FILE_TARGET_DDRC = 4,
|
|
88
88
|
FILE_TARGET_DDRE = 5,
|
|
89
|
-
FILE_TARGET_FLASH = 6
|
|
90
|
-
FILE_TARGET_RADIO = 7
|
|
89
|
+
FILE_TARGET_FLASH = 6,// for IQ2
|
|
90
|
+
FILE_TARGET_RADIO = 7,// for IQ2
|
|
91
91
|
FILE_TARGET_A1 = 13,
|
|
92
92
|
FILE_TARGET_B1 = 14,
|
|
93
93
|
FILE_TARGET_B2 = 15
|
package/dist/VexCRC.d.ts
CHANGED
package/dist/VexConnection.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { VexEventTarget } from "./VexEvent";
|
|
4
|
-
import { type ProgramIniConfig } from "./VexIniConfig";
|
|
5
|
-
import {
|
|
6
|
-
import { type
|
|
1
|
+
import { AckType, FileDownloadTarget, type IFileBasicInfo, type IFileWriteRequest, type IPacketCallback, type MatchMode, type SlotNumber, type SelectDashScreen } from "./Vex.js";
|
|
2
|
+
import { VexSerialError } from "./VexError.js";
|
|
3
|
+
import { VexEventTarget } from "./VexEvent.js";
|
|
4
|
+
import { type ProgramIniConfig } from "./VexIniConfig.js";
|
|
5
|
+
import { Result, ResultAsync } from "neverthrow";
|
|
6
|
+
import { MatchStatusReplyD2HPacket, DeviceBoundPacket, MatchModeReplyD2HPacket, GetSystemStatusReplyD2HPacket, type HostBoundPacket, Query1ReplyD2HPacket, LoadFileActionReplyD2HPacket, GetSystemFlagsReplyD2HPacket, GetRadioStatusReplyD2HPacket, GetDeviceStatusReplyD2HPacket, SendDashTouchReplyD2HPacket, SelectDashReplyD2HPacket, ScreenCaptureReplyD2HPacket } from "./VexPacket.js";
|
|
7
|
+
import { type VexFirmwareVersion } from "./VexFirmwareVersion.js";
|
|
7
8
|
/**
|
|
8
9
|
* A connection to a V5 device.
|
|
9
10
|
* Emit events: connected, disconnected
|
|
@@ -15,31 +16,88 @@ export declare class VexSerialConnection extends VexEventTarget {
|
|
|
15
16
|
port: SerialPort | undefined;
|
|
16
17
|
serial: Serial;
|
|
17
18
|
callbacksQueue: IPacketCallback[];
|
|
19
|
+
private _onPortDisconnect;
|
|
20
|
+
private _closePromise;
|
|
21
|
+
private _wasConnected;
|
|
22
|
+
protected fileTransferTail: Promise<unknown>;
|
|
23
|
+
protected fileTransferDepth: number;
|
|
18
24
|
get isConnected(): boolean;
|
|
25
|
+
get isFileTransferring(): boolean;
|
|
19
26
|
constructor(serial: Serial);
|
|
20
27
|
close(): Promise<void>;
|
|
21
|
-
|
|
28
|
+
private _hasOpenResources;
|
|
29
|
+
private _doClose;
|
|
30
|
+
/**
|
|
31
|
+
* Open a port. The result is `Err` only when a connection is already
|
|
32
|
+
* open (programmer error); otherwise the underlying `boolean |
|
|
33
|
+
* undefined` semantics are preserved: `true` = opened, `false` =
|
|
34
|
+
* the port was busy, `undefined` = no matching port was selected.
|
|
35
|
+
*/
|
|
36
|
+
open(use?: number | undefined, askUser?: boolean): ResultAsync<boolean | undefined, VexSerialError>;
|
|
37
|
+
private _open;
|
|
22
38
|
writeData(rawData: DeviceBoundPacket | Uint8Array, resolve: (data: HostBoundPacket | ArrayBuffer | AckType) => void, timeout?: number): void;
|
|
23
39
|
writeDataAsync(rawData: DeviceBoundPacket | Uint8Array, timeout?: number): Promise<HostBoundPacket | ArrayBuffer | AckType>;
|
|
24
40
|
protected readData(cache: Uint8Array, expectedSize: number): Promise<Uint8Array>;
|
|
25
41
|
protected startReader(): Promise<void>;
|
|
26
|
-
query1():
|
|
27
|
-
getSystemVersion():
|
|
42
|
+
query1(): ResultAsync<Query1ReplyD2HPacket, VexSerialError>;
|
|
43
|
+
getSystemVersion(): ResultAsync<VexFirmwareVersion, VexSerialError>;
|
|
28
44
|
}
|
|
29
45
|
export declare class V5SerialConnection extends VexSerialConnection {
|
|
30
46
|
filters: SerialPortFilter[];
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Serialize every transfer that touches the device's file-transfer mode
|
|
49
|
+
* through a single connection-level queue. Each call returns the prior
|
|
50
|
+
* tail and chains after it, so transfers always execute in request
|
|
51
|
+
* order without packet interleaving.
|
|
52
|
+
*/
|
|
53
|
+
withFileTransfer<T>(operation: () => Promise<T>): Promise<T>;
|
|
54
|
+
getDeviceStatus(): ResultAsync<GetDeviceStatusReplyD2HPacket, VexSerialError>;
|
|
55
|
+
getRadioStatus(): ResultAsync<GetRadioStatusReplyD2HPacket, VexSerialError>;
|
|
56
|
+
getSystemFlags(): ResultAsync<GetSystemFlagsReplyD2HPacket, VexSerialError>;
|
|
57
|
+
getSystemStatus(timeout?: number): ResultAsync<GetSystemStatusReplyD2HPacket, VexSerialError>;
|
|
58
|
+
getMatchStatus(): ResultAsync<MatchStatusReplyD2HPacket, VexSerialError>;
|
|
59
|
+
/**
|
|
60
|
+
* Upload an entire program (INI, optional cold binary, and the user
|
|
61
|
+
* binary) under a single connection-level transaction so that no other
|
|
62
|
+
* file-transfer request can interleave with the multi-file write.
|
|
63
|
+
*/
|
|
64
|
+
uploadProgramToDevice(iniConfig: ProgramIniConfig, binFileBuf: Uint8Array, coldFileBuf: Uint8Array | undefined, progressCallback: (state: string, current: number, total: number) => void): ResultAsync<boolean, VexSerialError>;
|
|
65
|
+
private _uploadProgramToDevice;
|
|
66
|
+
downloadFileToHost(request: IFileBasicInfo, downloadTarget?: FileDownloadTarget, progressCallback?: (current: number, total: number) => void): ResultAsync<Uint8Array, VexSerialError>;
|
|
67
|
+
/**
|
|
68
|
+
* Run a download without acquiring the connection-level transfer lock.
|
|
69
|
+
* Intended for callers that already hold a transaction (such as
|
|
70
|
+
* `captureScreen`) and need to issue the download within a larger
|
|
71
|
+
* queued operation.
|
|
72
|
+
*/
|
|
73
|
+
downloadFileToHostUnlocked(request: IFileBasicInfo, downloadTarget?: FileDownloadTarget, progressCallback?: (current: number, total: number) => void): ResultAsync<Uint8Array, VexSerialError>;
|
|
74
|
+
private _downloadFileToHostUnlocked;
|
|
75
|
+
uploadFileToDevice(request: IFileWriteRequest, progressCallback?: (current: number, total: number) => void): ResultAsync<boolean, VexSerialError>;
|
|
76
|
+
uploadFileToDeviceUnlocked(request: IFileWriteRequest, progressCallback?: (current: number, total: number) => void): Promise<Result<boolean, VexSerialError>>;
|
|
77
|
+
/**
|
|
78
|
+
* Erase a single file under a single transfer-mode session, exiting
|
|
79
|
+
* file-transfer mode in a `finally` block regardless of how the
|
|
80
|
+
* operation completes.
|
|
81
|
+
*/
|
|
82
|
+
removeFile(request: IFileBasicInfo | string): ResultAsync<void, VexSerialError>;
|
|
83
|
+
/**
|
|
84
|
+
* Erase every file in the user vendor namespace under a single
|
|
85
|
+
* transfer-mode session.
|
|
86
|
+
*/
|
|
87
|
+
removeAllFiles(): ResultAsync<void, VexSerialError>;
|
|
88
|
+
/**
|
|
89
|
+
* Issue the screen-capture command and validate that the device
|
|
90
|
+
* acknowledged it. Callers must inspect the returned packet (or the
|
|
91
|
+
* error result on NACK) before downloading the framebuffer so that a
|
|
92
|
+
* rejected request performs no download.
|
|
93
|
+
*/
|
|
94
|
+
captureScreenSetup(): ResultAsync<ScreenCaptureReplyD2HPacket, VexSerialError>;
|
|
95
|
+
captureScreen(progressCallback?: (current: number, total: number) => void): ResultAsync<Uint8Array, VexSerialError>;
|
|
96
|
+
private _captureScreen;
|
|
97
|
+
setMatchMode(mode: MatchMode): ResultAsync<MatchModeReplyD2HPacket, VexSerialError>;
|
|
98
|
+
runProgram(value: SlotNumber | string): ResultAsync<LoadFileActionReplyD2HPacket, VexSerialError>;
|
|
99
|
+
loadProgram(value: SlotNumber | string): ResultAsync<LoadFileActionReplyD2HPacket, VexSerialError>;
|
|
100
|
+
stopProgram(): ResultAsync<LoadFileActionReplyD2HPacket, VexSerialError>;
|
|
101
|
+
mockTouch(x: number, y: number, press: boolean): ResultAsync<SendDashTouchReplyD2HPacket, VexSerialError>;
|
|
102
|
+
openScreen(screen: number | SelectDashScreen, port: number): ResultAsync<SelectDashReplyD2HPacket, VexSerialError>;
|
|
45
103
|
}
|
package/dist/VexDevice.d.ts
CHANGED
|
@@ -1,158 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
export declare function sleepUntilAsync(f: () => Promise<boolean>, timeout: number, interval?: number): Promise<boolean>;
|
|
9
|
-
export declare function sleepUntil(f: () => boolean, timeout: number, interval?: number): Promise<boolean>;
|
|
10
|
-
export declare function sleep(ms: number): Promise<unknown>;
|
|
11
|
-
export declare abstract class VexSerialDevice extends VexEventTarget {
|
|
12
|
-
connection: V5SerialConnection | undefined;
|
|
13
|
-
defaultSerial: Serial;
|
|
14
|
-
get isConnected(): boolean;
|
|
15
|
-
get deviceType(): SerialDeviceType | undefined;
|
|
16
|
-
constructor(defaultSerial: Serial);
|
|
17
|
-
abstract connect(conn?: V5SerialConnection): Promise<boolean>;
|
|
18
|
-
abstract disconnect(): void;
|
|
19
|
-
}
|
|
20
|
-
declare class V5SerialDeviceState {
|
|
21
|
-
_instance: V5SerialDevice;
|
|
22
|
-
_isFileTransferring: boolean;
|
|
23
|
-
brain: {
|
|
24
|
-
activeProgram: number;
|
|
25
|
-
battery: {
|
|
26
|
-
batteryPercent: number;
|
|
27
|
-
isCharging: boolean;
|
|
28
|
-
};
|
|
29
|
-
button: {
|
|
30
|
-
isPressed: boolean;
|
|
31
|
-
isDoublePressed: boolean;
|
|
32
|
-
};
|
|
33
|
-
cpu0Version: VexFirmwareVersion;
|
|
34
|
-
cpu1Version: VexFirmwareVersion;
|
|
35
|
-
isAvailable: boolean;
|
|
36
|
-
settings: {
|
|
37
|
-
isScreenReversed: boolean;
|
|
38
|
-
isWhiteTheme: boolean;
|
|
39
|
-
usingLanguage: number;
|
|
40
|
-
};
|
|
41
|
-
systemVersion: VexFirmwareVersion;
|
|
42
|
-
uniqueId: number;
|
|
43
|
-
};
|
|
44
|
-
controllers: ({
|
|
45
|
-
battery: number;
|
|
46
|
-
isAvailable: boolean;
|
|
47
|
-
isCharging: boolean;
|
|
48
|
-
} | {
|
|
49
|
-
battery: number;
|
|
50
|
-
isAvailable: boolean;
|
|
51
|
-
isCharging?: undefined;
|
|
52
|
-
})[];
|
|
53
|
-
devices: Array<ISmartDeviceInfo | undefined>;
|
|
54
|
-
isFieldControllerConnected: boolean;
|
|
55
|
-
matchMode: MatchMode;
|
|
56
|
-
radio: {
|
|
57
|
-
channel: number;
|
|
58
|
-
isAvailable: boolean;
|
|
59
|
-
isConnected: boolean;
|
|
60
|
-
isVexNet: boolean;
|
|
61
|
-
isRadioData: boolean;
|
|
62
|
-
latency: number;
|
|
63
|
-
signalQuality: number;
|
|
64
|
-
signalStrength: number;
|
|
65
|
-
};
|
|
66
|
-
constructor(instance: V5SerialDevice);
|
|
67
|
-
}
|
|
68
|
-
export declare class V5Brain {
|
|
69
|
-
private readonly state;
|
|
70
|
-
constructor(state: V5SerialDeviceState);
|
|
71
|
-
get isRunningProgram(): boolean;
|
|
72
|
-
get activeProgram(): number;
|
|
73
|
-
set activeProgram(value: number);
|
|
74
|
-
get battery(): V5Battery;
|
|
75
|
-
get button(): V5BrainButton;
|
|
76
|
-
get cpu0Version(): VexFirmwareVersion;
|
|
77
|
-
get cpu1Version(): VexFirmwareVersion;
|
|
78
|
-
get isAvailable(): boolean;
|
|
79
|
-
get settings(): V5BrainSettings;
|
|
80
|
-
get systemVersion(): VexFirmwareVersion;
|
|
81
|
-
get uniqueId(): number;
|
|
82
|
-
getValue(key: string): Promise<string | undefined>;
|
|
83
|
-
setValue(key: string, value: string): Promise<boolean>;
|
|
84
|
-
listFiles(vendor?: FileVendor): Promise<IFileHandle[] | undefined>;
|
|
85
|
-
listProgram(): Promise<IProgramInfo[] | undefined>;
|
|
86
|
-
readFile(request: IFileBasicInfo | string, downloadTarget?: FileDownloadTarget, progressCallback?: (current: number, total: number) => void): Promise<Uint8Array | undefined>;
|
|
87
|
-
removeFile(request: IFileBasicInfo | string): Promise<boolean | undefined>;
|
|
88
|
-
removeAllFiles(): Promise<boolean | undefined>;
|
|
89
|
-
uploadFirmware(publicUrl?: string, usingVersion?: string, progressCallback?: (state: string, current: number, total: number) => void): Promise<boolean | undefined>;
|
|
90
|
-
uploadProgram(iniConfig: ProgramIniConfig, binFileBuf: Uint8Array, coldFileBuf: Uint8Array | undefined, progressCallback: (state: string, current: number, total: number) => void): Promise<boolean | undefined>;
|
|
91
|
-
writeFile(request: IFileWriteRequest, progressCallback?: (current: number, total: number) => void): Promise<boolean | undefined>;
|
|
92
|
-
/**
|
|
93
|
-
*
|
|
94
|
-
* @param progressCallback Informs the progress of the download.
|
|
95
|
-
* @returns array of bytes where each pixel is represented by 3 consecutive bytes (rgb).
|
|
96
|
-
* This array's length is 272 width * 480 height * 3 channels = 391680 bytes.
|
|
97
|
-
*/
|
|
98
|
-
captureScreen(progressCallback?: (current: number, total: number) => void): Promise<Uint8Array | undefined>;
|
|
99
|
-
}
|
|
100
|
-
export declare class V5Battery {
|
|
101
|
-
private readonly state;
|
|
102
|
-
constructor(state: V5SerialDeviceState);
|
|
103
|
-
get batteryPercent(): number;
|
|
104
|
-
get isCharging(): boolean;
|
|
105
|
-
}
|
|
106
|
-
export declare class V5BrainButton {
|
|
107
|
-
private readonly state;
|
|
108
|
-
constructor(state: V5SerialDeviceState);
|
|
109
|
-
get isPressed(): boolean;
|
|
110
|
-
get isDoublePressed(): boolean;
|
|
111
|
-
}
|
|
112
|
-
export declare class V5BrainSettings {
|
|
113
|
-
private readonly state;
|
|
114
|
-
constructor(state: V5SerialDeviceState);
|
|
115
|
-
get isScreenReversed(): boolean;
|
|
116
|
-
get isWhiteTheme(): boolean;
|
|
117
|
-
get usingLanguage(): number;
|
|
118
|
-
}
|
|
119
|
-
export declare class V5Controller {
|
|
120
|
-
private readonly state;
|
|
121
|
-
private readonly controllerIndex;
|
|
122
|
-
constructor(state: V5SerialDeviceState, controllerIndex: number);
|
|
123
|
-
get batteryPercent(): number;
|
|
124
|
-
get isMasterController(): boolean;
|
|
125
|
-
get isAvailable(): boolean;
|
|
126
|
-
get isCharging(): boolean | undefined;
|
|
127
|
-
}
|
|
128
|
-
export declare class V5SmartDevice {
|
|
129
|
-
private readonly state;
|
|
130
|
-
private readonly deviceIndex;
|
|
131
|
-
constructor(state: V5SerialDeviceState, index: number);
|
|
132
|
-
protected getDeviceInfo(): ISmartDeviceInfo | undefined;
|
|
133
|
-
get isAvailable(): boolean;
|
|
134
|
-
get port(): number;
|
|
135
|
-
get type(): SmartDeviceType;
|
|
136
|
-
get version(): number;
|
|
137
|
-
}
|
|
138
|
-
export declare class V5Radio {
|
|
139
|
-
private readonly state;
|
|
140
|
-
constructor(state: V5SerialDeviceState);
|
|
141
|
-
get channel(): number;
|
|
142
|
-
get isAvailable(): boolean;
|
|
143
|
-
get isConnected(): boolean;
|
|
144
|
-
get isVexNet(): boolean;
|
|
145
|
-
get isRadioData(): boolean;
|
|
146
|
-
get latency(): number;
|
|
147
|
-
changeChannel(channel: RadioChannelType): Promise<boolean>;
|
|
148
|
-
}
|
|
1
|
+
import { type MatchMode } from "./Vex.js";
|
|
2
|
+
import { V5SerialConnection } from "./VexConnection.js";
|
|
3
|
+
import { V5Brain, V5Controller, V5Radio, V5SerialDeviceState, V5SmartDevice, VexSerialDevice } from "./VexDeviceState.js";
|
|
4
|
+
import { VexSerialError } from "./VexError.js";
|
|
5
|
+
import { ResultAsync } from "neverthrow";
|
|
6
|
+
export { VexSerialDevice, V5Brain, V5Battery, V5BrainButton, V5BrainSettings, V5Controller, V5SmartDevice, V5Radio, V5SerialDeviceState, } from "./VexDeviceState.js";
|
|
7
|
+
export { sleep, sleepUntil, sleepUntilAsync, downloadFileFromInternet, uploadFirmware, } from "./VexFirmware.js";
|
|
149
8
|
export declare class V5SerialDevice extends VexSerialDevice {
|
|
150
9
|
autoReconnect: boolean;
|
|
151
10
|
autoRefresh: boolean;
|
|
152
11
|
pauseRefreshOnFileTransfer: boolean;
|
|
153
12
|
protected _isReconnecting: boolean;
|
|
13
|
+
private _isDisconnecting;
|
|
154
14
|
private _refreshInterval;
|
|
155
15
|
state: V5SerialDeviceState;
|
|
16
|
+
private _disposed;
|
|
17
|
+
private _refreshGeneration;
|
|
156
18
|
constructor(defaultSerial: Serial);
|
|
157
19
|
get isV5Controller(): boolean;
|
|
158
20
|
get brain(): V5Brain;
|
|
@@ -160,18 +22,42 @@ export declare class V5SerialDevice extends VexSerialDevice {
|
|
|
160
22
|
get devices(): V5SmartDevice[];
|
|
161
23
|
get isFieldControllerConnected(): boolean;
|
|
162
24
|
get matchMode(): MatchMode;
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Setting this property dispatches a fire-and-forget
|
|
27
|
+
* request whose result cannot be observed. Use {@link setMatchMode}
|
|
28
|
+
* instead, which returns a {@link ResultAsync} that resolves to an
|
|
29
|
+
* error result when the device refuses or is disconnected.
|
|
30
|
+
*/
|
|
163
31
|
set matchMode(value: MatchMode);
|
|
32
|
+
/**
|
|
33
|
+
* Update the match mode and resolve only after the device
|
|
34
|
+
* acknowledges the command. Resolves to an error result when the
|
|
35
|
+
* device NACKs, the request times out, or no connection is open.
|
|
36
|
+
*/
|
|
37
|
+
setMatchMode(mode: MatchMode): ResultAsync<void, VexSerialError>;
|
|
164
38
|
get radio(): V5Radio;
|
|
165
|
-
mockTouch(x: number, y: number, press: boolean):
|
|
166
|
-
connect(conn?: V5SerialConnection):
|
|
39
|
+
mockTouch(x: number, y: number, press: boolean): ResultAsync<void, VexSerialError>;
|
|
40
|
+
connect(conn?: V5SerialConnection): ResultAsync<void, VexSerialError>;
|
|
41
|
+
private _connect;
|
|
167
42
|
disconnect(): Promise<void>;
|
|
168
43
|
dispose(): Promise<void>;
|
|
169
44
|
/**
|
|
170
|
-
* @param timeout defaults to 0. If timeout is 0, then it will attempt to reconnect forever
|
|
171
|
-
* @returns
|
|
45
|
+
* @param timeout defaults to 0. If timeout is 0, then it will attempt to reconnect forever.
|
|
172
46
|
*/
|
|
173
|
-
reconnect(timeout?: number):
|
|
47
|
+
reconnect(timeout?: number): ResultAsync<void, VexSerialError>;
|
|
48
|
+
private _reconnect;
|
|
49
|
+
private waitForReconnectToFinish;
|
|
174
50
|
private doAfterConnect;
|
|
175
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Refresh the high-level device snapshot. All required replies are
|
|
53
|
+
* collected before any public state is mutated, so callers never see
|
|
54
|
+
* a half-updated view. A failed or missing reply resolves to an `Ok`
|
|
55
|
+
* of `false` (the previous snapshot is preserved and only the
|
|
56
|
+
* `isAvailable` flag is updated) so transient communication loss does
|
|
57
|
+
* not surface as a hard error result.
|
|
58
|
+
*/
|
|
59
|
+
refresh(): ResultAsync<boolean, VexSerialError>;
|
|
60
|
+
private _refresh;
|
|
61
|
+
private _buildSnapshot;
|
|
62
|
+
private _applySnapshotIfCurrent;
|
|
176
63
|
}
|
|
177
|
-
export {};
|
|
@@ -1,25 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
import { type
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export declare function sleepUntil(f: () => boolean, timeout: number, interval?: number): Promise<boolean>;
|
|
10
|
-
export declare function sleep(ms: number): Promise<unknown>;
|
|
1
|
+
import { type MatchMode, SerialDeviceType, type SlotNumber, type ISmartDeviceInfo, SmartDeviceType, FileVendor, type IProgramInfo, type IFileHandle, type IFileBasicInfo, type IFileWriteRequest, FileDownloadTarget, RadioChannelType } from "./Vex.js";
|
|
2
|
+
import { type V5SerialConnection } from "./VexConnection.js";
|
|
3
|
+
import { VexEventTarget } from "./VexEvent.js";
|
|
4
|
+
import { VexFirmwareVersion } from "./VexFirmwareVersion.js";
|
|
5
|
+
import { type ProgramIniConfig } from "./VexIniConfig.js";
|
|
6
|
+
import { VexSerialError } from "./VexError.js";
|
|
7
|
+
import { ResultAsync } from "neverthrow";
|
|
8
|
+
import type { V5SerialDevice } from "./VexDevice.js";
|
|
11
9
|
export declare abstract class VexSerialDevice extends VexEventTarget {
|
|
12
10
|
connection: V5SerialConnection | undefined;
|
|
13
11
|
defaultSerial: Serial;
|
|
14
12
|
get isConnected(): boolean;
|
|
15
13
|
get deviceType(): SerialDeviceType | undefined;
|
|
16
14
|
constructor(defaultSerial: Serial);
|
|
17
|
-
abstract connect(conn?: V5SerialConnection):
|
|
18
|
-
abstract disconnect(): void
|
|
15
|
+
abstract connect(conn?: V5SerialConnection): ResultAsync<void, VexSerialError>;
|
|
16
|
+
abstract disconnect(): Promise<void>;
|
|
19
17
|
}
|
|
20
|
-
declare class V5SerialDeviceState {
|
|
18
|
+
export declare class V5SerialDeviceState {
|
|
21
19
|
_instance: V5SerialDevice;
|
|
22
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Counter used only to pause automatic refresh while a file transfer
|
|
22
|
+
* is in flight. This is not a mutex: serialisation of transfer
|
|
23
|
+
* operations lives on the {@link V5SerialConnection} transaction
|
|
24
|
+
* queue. The counter is exposed via {@link isFileTransferring} so the
|
|
25
|
+
* refresh loop can skip work during transfers.
|
|
26
|
+
*/
|
|
27
|
+
private refreshPauseDepth;
|
|
28
|
+
get isFileTransferring(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Increment the refresh-pause depth, run the operation, and decrement
|
|
31
|
+
* the depth again. The actual transfer mutex lives on the connection,
|
|
32
|
+
* so this method does not serialise anything; it only signals the
|
|
33
|
+
* device that a transfer is in progress so refresh polling is paused.
|
|
34
|
+
*/
|
|
35
|
+
withFileTransfer<T>(operation: () => PromiseLike<T>): Promise<T>;
|
|
23
36
|
brain: {
|
|
24
37
|
activeProgram: number;
|
|
25
38
|
battery: {
|
|
@@ -70,7 +83,31 @@ export declare class V5Brain {
|
|
|
70
83
|
constructor(state: V5SerialDeviceState);
|
|
71
84
|
get isRunningProgram(): boolean;
|
|
72
85
|
get activeProgram(): number;
|
|
86
|
+
/**
|
|
87
|
+
* @deprecated Setting this property dispatches a fire-and-forget
|
|
88
|
+
* request that cannot be awaited. Use {@link setActiveProgram}
|
|
89
|
+
* instead, which returns a {@link ResultAsync} that resolves to an
|
|
90
|
+
* error result when the device refuses or is disconnected.
|
|
91
|
+
*/
|
|
73
92
|
set activeProgram(value: number);
|
|
93
|
+
/**
|
|
94
|
+
* Load a program slot on the brain, or stop the currently running
|
|
95
|
+
* program when called with `0`. Resolves to an error result when the
|
|
96
|
+
* device refuses, the request times out, or no connection is open.
|
|
97
|
+
*/
|
|
98
|
+
setActiveProgram(value: SlotNumber | 0): ResultAsync<void, VexSerialError>;
|
|
99
|
+
/**
|
|
100
|
+
* Request that the brain start running the program in the given slot.
|
|
101
|
+
* Resolves to an error result when the device refuses, the request
|
|
102
|
+
* times out, or no connection is open.
|
|
103
|
+
*/
|
|
104
|
+
runProgram(slot: SlotNumber | string): ResultAsync<void, VexSerialError>;
|
|
105
|
+
/**
|
|
106
|
+
* Request that the brain stop the currently running program. Resolves
|
|
107
|
+
* to an error result when the device refuses, the request times out,
|
|
108
|
+
* or no connection is open.
|
|
109
|
+
*/
|
|
110
|
+
stopProgram(): ResultAsync<void, VexSerialError>;
|
|
74
111
|
get battery(): V5Battery;
|
|
75
112
|
get button(): V5BrainButton;
|
|
76
113
|
get cpu0Version(): VexFirmwareVersion;
|
|
@@ -79,23 +116,23 @@ export declare class V5Brain {
|
|
|
79
116
|
get settings(): V5BrainSettings;
|
|
80
117
|
get systemVersion(): VexFirmwareVersion;
|
|
81
118
|
get uniqueId(): number;
|
|
82
|
-
getValue(key: string):
|
|
83
|
-
setValue(key: string, value: string):
|
|
84
|
-
listFiles(vendor?: FileVendor):
|
|
85
|
-
listProgram():
|
|
86
|
-
readFile(request: IFileBasicInfo | string, downloadTarget?: FileDownloadTarget, progressCallback?: (current: number, total: number) => void):
|
|
87
|
-
removeFile(request: IFileBasicInfo | string):
|
|
88
|
-
removeAllFiles():
|
|
89
|
-
uploadFirmware(publicUrl?: string, usingVersion?: string, progressCallback?: (state: string, current: number, total: number) => void):
|
|
90
|
-
uploadProgram(iniConfig: ProgramIniConfig, binFileBuf: Uint8Array, coldFileBuf: Uint8Array | undefined, progressCallback: (state: string, current: number, total: number) => void):
|
|
91
|
-
writeFile(request: IFileWriteRequest, progressCallback?: (current: number, total: number) => void):
|
|
119
|
+
getValue(key: string): ResultAsync<string | undefined, VexSerialError>;
|
|
120
|
+
setValue(key: string, value: string): ResultAsync<void, VexSerialError>;
|
|
121
|
+
listFiles(vendor?: FileVendor): ResultAsync<IFileHandle[], VexSerialError>;
|
|
122
|
+
listProgram(): ResultAsync<IProgramInfo[], VexSerialError>;
|
|
123
|
+
readFile(request: IFileBasicInfo | string, downloadTarget?: FileDownloadTarget, progressCallback?: (current: number, total: number) => void): ResultAsync<Uint8Array, VexSerialError>;
|
|
124
|
+
removeFile(request: IFileBasicInfo | string): ResultAsync<void, VexSerialError>;
|
|
125
|
+
removeAllFiles(): ResultAsync<void, VexSerialError>;
|
|
126
|
+
uploadFirmware(publicUrl?: string, usingVersion?: string, progressCallback?: (state: string, current: number, total: number) => void): ResultAsync<boolean, VexSerialError>;
|
|
127
|
+
uploadProgram(iniConfig: ProgramIniConfig, binFileBuf: Uint8Array, coldFileBuf: Uint8Array | undefined, progressCallback: (state: string, current: number, total: number) => void): ResultAsync<boolean, VexSerialError>;
|
|
128
|
+
writeFile(request: IFileWriteRequest, progressCallback?: (current: number, total: number) => void): ResultAsync<boolean, VexSerialError>;
|
|
92
129
|
/**
|
|
93
130
|
*
|
|
94
131
|
* @param progressCallback Informs the progress of the download.
|
|
95
132
|
* @returns array of bytes where each pixel is represented by 3 consecutive bytes (rgb).
|
|
96
133
|
* This array's length is 272 width * 480 height * 3 channels = 391680 bytes.
|
|
97
134
|
*/
|
|
98
|
-
captureScreen(progressCallback?: (current: number, total: number) => void):
|
|
135
|
+
captureScreen(progressCallback?: (current: number, total: number) => void): ResultAsync<Uint8Array, VexSerialError>;
|
|
99
136
|
}
|
|
100
137
|
export declare class V5Battery {
|
|
101
138
|
private readonly state;
|
|
@@ -144,34 +181,5 @@ export declare class V5Radio {
|
|
|
144
181
|
get isVexNet(): boolean;
|
|
145
182
|
get isRadioData(): boolean;
|
|
146
183
|
get latency(): number;
|
|
147
|
-
changeChannel(channel: RadioChannelType):
|
|
148
|
-
}
|
|
149
|
-
export declare class V5SerialDevice extends VexSerialDevice {
|
|
150
|
-
autoReconnect: boolean;
|
|
151
|
-
autoRefresh: boolean;
|
|
152
|
-
pauseRefreshOnFileTransfer: boolean;
|
|
153
|
-
protected _isReconnecting: boolean;
|
|
154
|
-
private _refreshInterval;
|
|
155
|
-
state: V5SerialDeviceState;
|
|
156
|
-
constructor(defaultSerial: Serial);
|
|
157
|
-
get isV5Controller(): boolean;
|
|
158
|
-
get brain(): V5Brain;
|
|
159
|
-
get controllers(): [V5Controller, V5Controller];
|
|
160
|
-
get devices(): V5SmartDevice[];
|
|
161
|
-
get isFieldControllerConnected(): boolean;
|
|
162
|
-
get matchMode(): MatchMode;
|
|
163
|
-
set matchMode(value: MatchMode);
|
|
164
|
-
get radio(): V5Radio;
|
|
165
|
-
mockTouch(x: number, y: number, press: boolean): Promise<boolean>;
|
|
166
|
-
connect(conn?: V5SerialConnection): Promise<boolean>;
|
|
167
|
-
disconnect(): Promise<void>;
|
|
168
|
-
dispose(): Promise<void>;
|
|
169
|
-
/**
|
|
170
|
-
* @param timeout defaults to 0. If timeout is 0, then it will attempt to reconnect forever
|
|
171
|
-
* @returns
|
|
172
|
-
*/
|
|
173
|
-
reconnect(timeout?: number): Promise<boolean>;
|
|
174
|
-
private doAfterConnect;
|
|
175
|
-
refresh(): Promise<boolean>;
|
|
184
|
+
changeChannel(channel: RadioChannelType): ResultAsync<void, VexSerialError>;
|
|
176
185
|
}
|
|
177
|
-
export {};
|