@v5x/serial 0.5.5 → 0.5.7
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 +44 -13
- package/dist/Vex.d.ts +3 -1
- package/dist/VexCRC.d.ts +0 -11
- package/dist/VexConnection.d.ts +77 -10
- package/dist/VexDevice.d.ts +32 -2
- package/dist/VexDeviceState.d.ts +39 -17
- package/dist/VexError.d.ts +5 -1
- package/dist/VexEvent.d.ts +14 -10
- package/dist/VexFirmware.d.ts +5 -2
- package/dist/VexFirmwareVersion.d.ts +4 -43
- package/dist/VexIniConfig.d.ts +0 -1
- package/dist/VexPacketBase.d.ts +5 -2
- package/dist/VexPacketCore.d.ts +5 -0
- package/dist/VexPacketEncoder.d.ts +13 -30
- package/dist/VexPacketModels.d.ts +1 -12
- package/dist/VexPacketRegistry.d.ts +3 -0
- package/dist/VexPacketView.d.ts +2 -0
- package/dist/VexScreenCapture.d.ts +2 -0
- package/dist/VexTransfers.d.ts +1 -0
- package/dist/index.cjs +1291 -1818
- package/dist/index.cjs.map +19 -19
- package/dist/index.js +1392 -1872
- package/dist/index.js.map +19 -19
- package/dist/packet-core.cjs +383 -0
- package/dist/packet-core.cjs.map +14 -0
- package/dist/packet-core.js +341 -0
- package/dist/packet-core.js.map +14 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -4,9 +4,8 @@ TypeScript implementation of the VEX V5 serial protocol.
|
|
|
4
4
|
|
|
5
5
|
See the [serial library documentation](https://docs.v5x.dev/serial/overview) for browser setup, guides, and high-level API reference.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
packets.
|
|
7
|
+
It covers connecting to V5 devices over the Web Serial API, reading device
|
|
8
|
+
state, transferring files, and working with protocol packets.
|
|
10
9
|
|
|
11
10
|
## Install
|
|
12
11
|
|
|
@@ -30,7 +29,10 @@ if (opened.isErr()) {
|
|
|
30
29
|
console.error(opened.error); // VexSerialError with a stable .kind
|
|
31
30
|
return;
|
|
32
31
|
}
|
|
33
|
-
|
|
32
|
+
if (opened.value !== "opened") {
|
|
33
|
+
console.error(`Unable to open a compatible port: ${opened.value}`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
34
36
|
|
|
35
37
|
const status = await connection.getSystemStatus();
|
|
36
38
|
if (status.isOk()) {
|
|
@@ -47,7 +49,7 @@ can open.
|
|
|
47
49
|
The package ships ESM, CommonJS, and TypeScript declarations. Packet and version
|
|
48
50
|
utilities work in Bun or Node.js, but direct browser device connections require
|
|
49
51
|
the Web Serial API. The `@v5x/cli` package is separate and currently supports
|
|
50
|
-
Linux
|
|
52
|
+
Linux and macOS. Windows requires a different CLI serial backend.
|
|
51
53
|
|
|
52
54
|
## Common Exports
|
|
53
55
|
|
|
@@ -64,10 +66,9 @@ Linux only.
|
|
|
64
66
|
|
|
65
67
|
## Result-returning async APIs
|
|
66
68
|
|
|
67
|
-
All public async methods return `ResultAsync<T, VexSerialError
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
report errors through the result channel:
|
|
69
|
+
All public async methods return `ResultAsync<T, VexSerialError>`, so failures
|
|
70
|
+
are explicit in the type system rather than thrown. State-changing operations
|
|
71
|
+
are awaitable and report errors through the result channel:
|
|
71
72
|
|
|
72
73
|
```ts
|
|
73
74
|
const r = await device.setMatchMode("disabled");
|
|
@@ -83,9 +84,9 @@ removed. Migrate to the corresponding `setMatchMode()` / `setActiveProgram()`
|
|
|
83
84
|
methods and handle the returned `Result`.
|
|
84
85
|
|
|
85
86
|
Legacy methods that resolved to `false`, `null`, or `undefined` on failure now
|
|
86
|
-
return a typed `Err` instead
|
|
87
|
-
the `Ok` channel
|
|
88
|
-
|
|
87
|
+
return a typed `Err` instead. `open()` reports non-error connection outcomes on
|
|
88
|
+
the `Ok` channel as `"opened"`, `"busy"`, or `"no-port"`; only `"opened"`
|
|
89
|
+
indicates an established connection.
|
|
89
90
|
|
|
90
91
|
## Transfers and timeouts
|
|
91
92
|
|
|
@@ -97,7 +98,7 @@ transfer is active by default.
|
|
|
97
98
|
Protocol requests default to a 1,000 ms response timeout. Individual transfer
|
|
98
99
|
phases use longer timeouts where erase, write, or exit operations need them.
|
|
99
100
|
`reconnect(0)` waits indefinitely, while a positive reconnect timeout is a total
|
|
100
|
-
deadline in milliseconds. A timeout or NACK
|
|
101
|
+
deadline in milliseconds. A timeout or NACK surfaces as a `VexProtocolError`
|
|
101
102
|
(or a related `VexSerialError` subclass) through the `Result` error channel; it
|
|
102
103
|
does not cancel work already running on the device.
|
|
103
104
|
|
|
@@ -114,3 +115,33 @@ bun run build
|
|
|
114
115
|
```
|
|
115
116
|
|
|
116
117
|
The build emits JavaScript bundles and TypeScript declarations under `dist/`.
|
|
118
|
+
|
|
119
|
+
### Packet registry and browser bundle measurement
|
|
120
|
+
|
|
121
|
+
The complete entry point registers every reply class explicitly. Packet
|
|
122
|
+
decoding no longer discovers classes by enumerating the packet-model module at
|
|
123
|
+
runtime. Consumers that only need framing, CRC, packet base classes, and a
|
|
124
|
+
custom reply registry can import `@v5x/serial/packet-core`; that entry point
|
|
125
|
+
does not retain file-transfer, firmware, screenshot, or dashboard models.
|
|
126
|
+
Register only the reply classes the application accepts with
|
|
127
|
+
`PacketEncoder.getInstance().registerPacketTypes(...)`.
|
|
128
|
+
|
|
129
|
+
Run `bun run measure:bundles` in this package to report reproducible minified
|
|
130
|
+
byte sizes for the complete browser entry and the packet-core entry.
|
|
131
|
+
|
|
132
|
+
### File-transfer window semantics
|
|
133
|
+
|
|
134
|
+
The `windowSize` returned by `InitFileTransferReplyD2HPacket` is the maximum
|
|
135
|
+
data size for one `ReadFile` or `WriteFile` block. It is not a count of blocks
|
|
136
|
+
that may be outstanding. This follows from the wire model: read and write
|
|
137
|
+
replies carry only the shared CDC2 command and function IDs; write replies have
|
|
138
|
+
no address, sequence number, or request identifier with which to correlate an
|
|
139
|
+
individual outstanding block. A read address can validate a reply after it is
|
|
140
|
+
routed, but cannot make write failures unambiguous.
|
|
141
|
+
|
|
142
|
+
Transfers therefore intentionally remain stop-and-wait. The advertised value
|
|
143
|
+
is clamped to the library's 4096-byte block limit and used only as the chunk
|
|
144
|
+
size. There is no safe before/after pipelining benchmark to run because the
|
|
145
|
+
protocol does not expose the correlation needed to enable pipelining without
|
|
146
|
+
risking data corruption. Hardware throughput remains dependent on one USB
|
|
147
|
+
round trip per block.
|
package/dist/Vex.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="dom-serial" preserve="true" />
|
|
1
2
|
import { type VexFirmwareVersion } from "./VexFirmwareVersion.js";
|
|
2
3
|
import { type HostBoundPacket } from "./VexPacket.js";
|
|
3
4
|
export declare const USER_PROG_CHUNK_SIZE = 4096;
|
|
@@ -134,7 +135,8 @@ export declare enum AckType {
|
|
|
134
135
|
CDC2_NACK_FILE_EXISTS = 219,
|
|
135
136
|
CDC2_NACK_FILE_SYS_FULL = 220,
|
|
136
137
|
TIMEOUT = 256,
|
|
137
|
-
WRITE_ERROR = 257
|
|
138
|
+
WRITE_ERROR = 257,
|
|
139
|
+
NOT_CONNECTED = 258
|
|
138
140
|
}
|
|
139
141
|
export declare enum SmartDeviceType {
|
|
140
142
|
EMPTY = 0,
|
package/dist/VexCRC.d.ts
CHANGED
|
@@ -2,17 +2,6 @@ export declare class CrcGenerator {
|
|
|
2
2
|
crc32Table: Uint32Array;
|
|
3
3
|
static POLYNOMIAL_CRC32: number;
|
|
4
4
|
static POLYNOMIAL_CRC16: number;
|
|
5
|
-
constructor();
|
|
6
|
-
/**
|
|
7
|
-
* Calculate CRC16 for buffer
|
|
8
|
-
*/
|
|
9
5
|
crc16(buf: Uint8Array, initValue: number): number;
|
|
10
|
-
/**
|
|
11
|
-
* Generate CRC32 reverse table
|
|
12
|
-
*/
|
|
13
|
-
crc32GenTable(): void;
|
|
14
|
-
/**
|
|
15
|
-
* Calculate CRC32 for buffer
|
|
16
|
-
*/
|
|
17
6
|
crc32(buf: Uint8Array, initValue: number): number;
|
|
18
7
|
}
|
package/dist/VexConnection.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="dom-serial" preserve="true" />
|
|
1
2
|
import { AckType, FileDownloadTarget, type IFileBasicInfo, type IFileWriteRequest, type IPacketCallback, type MatchMode, type SlotNumber, type SelectDashScreen } from "./Vex.js";
|
|
2
3
|
import { VexSerialError } from "./VexError.js";
|
|
3
4
|
import { VexEventTarget } from "./VexEvent.js";
|
|
@@ -5,40 +6,90 @@ import { type ProgramIniConfig } from "./VexIniConfig.js";
|
|
|
5
6
|
import { Result, ResultAsync } from "neverthrow";
|
|
6
7
|
import { MatchStatusReplyD2HPacket, DeviceBoundPacket, MatchModeReplyD2HPacket, GetSystemStatusReplyD2HPacket, type HostBoundPacket, Query1ReplyD2HPacket, LoadFileActionReplyD2HPacket, GetSystemFlagsReplyD2HPacket, GetRadioStatusReplyD2HPacket, GetDeviceStatusReplyD2HPacket, SendDashTouchReplyD2HPacket, SelectDashReplyD2HPacket, ScreenCaptureReplyD2HPacket } from "./VexPacket.js";
|
|
7
8
|
import { type VexFirmwareVersion } from "./VexFirmwareVersion.js";
|
|
9
|
+
type HostBoundPacketType<T extends HostBoundPacket> = {
|
|
10
|
+
new (data: ArrayBuffer | Uint8Array): T;
|
|
11
|
+
name: string;
|
|
12
|
+
};
|
|
13
|
+
/** Outcome of {@link VexSerialConnection.open}. */
|
|
14
|
+
export type OpenResult = "opened" | "busy" | "no-port";
|
|
15
|
+
/**
|
|
16
|
+
* Payload of the `warning` event: a non-fatal condition the library
|
|
17
|
+
* recovered from, surfaced so embedders can log or ignore it.
|
|
18
|
+
*/
|
|
19
|
+
export interface ConnectionWarning {
|
|
20
|
+
message: string;
|
|
21
|
+
details?: unknown;
|
|
22
|
+
}
|
|
23
|
+
export interface VexSerialConnectionEvents {
|
|
24
|
+
connected: undefined;
|
|
25
|
+
disconnected: undefined;
|
|
26
|
+
warning: ConnectionWarning;
|
|
27
|
+
}
|
|
8
28
|
/**
|
|
9
29
|
* A connection to a V5 device.
|
|
10
|
-
* Emit events: connected, disconnected
|
|
30
|
+
* Emit events: connected, disconnected, warning
|
|
11
31
|
*/
|
|
12
|
-
export declare class VexSerialConnection extends VexEventTarget {
|
|
32
|
+
export declare class VexSerialConnection extends VexEventTarget<VexSerialConnectionEvents> {
|
|
13
33
|
filters: SerialPortFilter[];
|
|
14
34
|
writer: WritableStreamDefaultWriter<unknown> | undefined;
|
|
15
35
|
reader: ReadableStreamDefaultReader<unknown> | undefined;
|
|
16
36
|
port: SerialPort | undefined;
|
|
17
37
|
serial: Serial;
|
|
18
|
-
|
|
38
|
+
private pendingCallbacks;
|
|
39
|
+
private rawCallbacks;
|
|
40
|
+
private pendingCommandTails;
|
|
19
41
|
private _onPortDisconnect;
|
|
20
42
|
private _closePromise;
|
|
43
|
+
private _openPromise;
|
|
44
|
+
private _isClosing;
|
|
21
45
|
private _wasConnected;
|
|
22
46
|
protected fileTransferTail: Promise<unknown>;
|
|
23
47
|
protected fileTransferDepth: number;
|
|
48
|
+
/** Pending callbacks, exposed as a snapshot for backwards compatibility. */
|
|
49
|
+
get callbacksQueue(): IPacketCallback[];
|
|
24
50
|
get isConnected(): boolean;
|
|
25
51
|
get isFileTransferring(): boolean;
|
|
26
52
|
constructor(serial: Serial);
|
|
53
|
+
protected reportWarning(message: string, details?: unknown): void;
|
|
54
|
+
/**
|
|
55
|
+
* Connection events are notifications only: a consumer callback must not
|
|
56
|
+
* alter the lifecycle of the serial transport that produced it.
|
|
57
|
+
*/
|
|
58
|
+
private emitSafely;
|
|
27
59
|
close(): Promise<void>;
|
|
60
|
+
private _closeAfterOpen;
|
|
28
61
|
private _hasOpenResources;
|
|
29
62
|
private _doClose;
|
|
30
63
|
/**
|
|
31
|
-
* Open a port.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
64
|
+
* Open a port. Resolves `"opened"` when a connection is established,
|
|
65
|
+
* `"busy"` when the matching port is already held elsewhere, and
|
|
66
|
+
* `"no-port"` when no matching port was selected. The result is `Err`
|
|
67
|
+
* when a connection is already open (programmer error) or when the
|
|
68
|
+
* port fails to open (permissions, dead device, ...). Concurrent calls
|
|
69
|
+
* join the same open attempt and receive its result.
|
|
35
70
|
*/
|
|
36
|
-
open(use?: number
|
|
71
|
+
open(use?: number, askUser?: boolean): ResultAsync<OpenResult, VexSerialError>;
|
|
37
72
|
private _open;
|
|
38
|
-
writeData(rawData: DeviceBoundPacket | Uint8Array, resolve: (data: HostBoundPacket | ArrayBuffer | AckType) => void, timeout?: number): void;
|
|
39
73
|
writeDataAsync(rawData: DeviceBoundPacket | Uint8Array, timeout?: number): Promise<HostBoundPacket | ArrayBuffer | AckType>;
|
|
40
|
-
|
|
74
|
+
/**
|
|
75
|
+
* A command ID identifies a reply packet type, not an individual request.
|
|
76
|
+
* Keep requests with the same reply identifiers off the wire until the
|
|
77
|
+
* preceding request has resolved, while allowing unrelated commands to run
|
|
78
|
+
* concurrently.
|
|
79
|
+
*/
|
|
80
|
+
private serializeCommand;
|
|
81
|
+
private writeDataAsyncUnserialized;
|
|
82
|
+
request<T extends HostBoundPacket>(packet: DeviceBoundPacket, ReplyType: HostBoundPacketType<T>, timeout?: number): ResultAsync<T, VexSerialError>;
|
|
83
|
+
protected readData(cache: ReceiveBuffer, expectedSize: number): Promise<void>;
|
|
41
84
|
protected startReader(): Promise<void>;
|
|
85
|
+
private pendingKey;
|
|
86
|
+
private getPendingQueue;
|
|
87
|
+
private enqueuePendingCallback;
|
|
88
|
+
private removePendingCallback;
|
|
89
|
+
private shiftPendingCallback;
|
|
90
|
+
private shiftRawCallback;
|
|
91
|
+
private hasPendingCallbacks;
|
|
92
|
+
private drainPendingCallbacks;
|
|
42
93
|
query1(): ResultAsync<Query1ReplyD2HPacket, VexSerialError>;
|
|
43
94
|
getSystemVersion(): ResultAsync<VexFirmwareVersion, VexSerialError>;
|
|
44
95
|
}
|
|
@@ -101,3 +152,19 @@ export declare class V5SerialConnection extends VexSerialConnection {
|
|
|
101
152
|
mockTouch(x: number, y: number, press: boolean): ResultAsync<SendDashTouchReplyD2HPacket, VexSerialError>;
|
|
102
153
|
openScreen(screen: number | SelectDashScreen, port: number): ResultAsync<SelectDashReplyD2HPacket, VexSerialError>;
|
|
103
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* A growable receive queue. Parsed packets are copied out before their bytes
|
|
157
|
+
* are discarded, so views into this reusable storage never escape the reader.
|
|
158
|
+
*/
|
|
159
|
+
declare class ReceiveBuffer {
|
|
160
|
+
private storage;
|
|
161
|
+
private start;
|
|
162
|
+
private end;
|
|
163
|
+
get byteLength(): number;
|
|
164
|
+
get bytes(): Uint8Array<ArrayBuffer>;
|
|
165
|
+
append(chunk: Uint8Array): void;
|
|
166
|
+
copy(length: number): Uint8Array<ArrayBuffer>;
|
|
167
|
+
discard(length: number): void;
|
|
168
|
+
private reserve;
|
|
169
|
+
}
|
|
170
|
+
export {};
|
package/dist/VexDevice.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="dom-serial" preserve="true" />
|
|
1
2
|
import { type MatchMode } from "./Vex.js";
|
|
2
3
|
import { V5SerialConnection } from "./VexConnection.js";
|
|
3
4
|
import { V5Brain, V5Controller, V5Radio, V5SerialDeviceState, V5SmartDevice, VexSerialDevice } from "./VexDeviceState.js";
|
|
@@ -5,17 +6,40 @@ import { VexSerialError } from "./VexError.js";
|
|
|
5
6
|
import { ResultAsync } from "neverthrow";
|
|
6
7
|
export { VexSerialDevice, V5Brain, V5Battery, V5BrainButton, V5BrainSettings, V5Controller, V5SmartDevice, V5Radio, V5SerialDeviceState, } from "./VexDeviceState.js";
|
|
7
8
|
export { sleep, sleepUntil, sleepUntilAsync, downloadFileFromInternet, uploadFirmware, } from "./VexFirmware.js";
|
|
9
|
+
export interface V5SerialDeviceOptions {
|
|
10
|
+
autoRefresh?: boolean;
|
|
11
|
+
refreshIntervalMs?: number;
|
|
12
|
+
}
|
|
8
13
|
export declare class V5SerialDevice extends VexSerialDevice {
|
|
9
14
|
autoReconnect: boolean;
|
|
10
|
-
autoRefresh: boolean;
|
|
11
15
|
pauseRefreshOnFileTransfer: boolean;
|
|
12
16
|
protected _isReconnecting: boolean;
|
|
13
17
|
private _isDisconnecting;
|
|
14
18
|
private _refreshInterval;
|
|
15
19
|
state: V5SerialDeviceState;
|
|
16
20
|
private _disposed;
|
|
21
|
+
private _lifecycleGeneration;
|
|
22
|
+
private _disconnectListener;
|
|
17
23
|
private _refreshGeneration;
|
|
18
|
-
|
|
24
|
+
private _autoRefresh;
|
|
25
|
+
private _refreshIntervalMs;
|
|
26
|
+
private _isLastRefreshComplete;
|
|
27
|
+
private readonly _brain;
|
|
28
|
+
private readonly _controllers;
|
|
29
|
+
private readonly _radio;
|
|
30
|
+
private readonly _deviceFacades;
|
|
31
|
+
/**
|
|
32
|
+
* Device lifecycle events are notifications only: consumer callbacks must
|
|
33
|
+
* not alter automatic refresh or reconnect work that produced them.
|
|
34
|
+
*/
|
|
35
|
+
private _emitSafely;
|
|
36
|
+
constructor(defaultSerial: Serial, options?: boolean | V5SerialDeviceOptions);
|
|
37
|
+
get autoRefresh(): boolean;
|
|
38
|
+
set autoRefresh(value: boolean);
|
|
39
|
+
get refreshIntervalMs(): number;
|
|
40
|
+
set refreshIntervalMs(value: number);
|
|
41
|
+
private _startRefreshInterval;
|
|
42
|
+
private _stopRefreshInterval;
|
|
19
43
|
get isV5Controller(): boolean;
|
|
20
44
|
get brain(): V5Brain;
|
|
21
45
|
get controllers(): [V5Controller, V5Controller];
|
|
@@ -47,7 +71,13 @@ export declare class V5SerialDevice extends VexSerialDevice {
|
|
|
47
71
|
reconnect(timeout?: number): ResultAsync<void, VexSerialError>;
|
|
48
72
|
private _reconnect;
|
|
49
73
|
private waitForReconnectToFinish;
|
|
74
|
+
protected createConnection(): V5SerialConnection;
|
|
75
|
+
private _isLifecycleCurrent;
|
|
76
|
+
private _staleLifecycleResult;
|
|
77
|
+
private _commitConnection;
|
|
78
|
+
private _detachDisconnectListener;
|
|
50
79
|
private doAfterConnect;
|
|
80
|
+
private _discardConnection;
|
|
51
81
|
/**
|
|
52
82
|
* Refresh the high-level device snapshot. All required replies are
|
|
53
83
|
* collected before any public state is mutated, so callers never see
|
package/dist/VexDeviceState.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="dom-serial" preserve="true" />
|
|
1
2
|
import { type MatchMode, SerialDeviceType, type SlotNumber, type ISmartDeviceInfo, SmartDeviceType, FileVendor, type IProgramInfo, type IFileHandle, type IFileBasicInfo, type IFileWriteRequest, FileDownloadTarget, RadioChannelType } from "./Vex.js";
|
|
2
3
|
import { type V5SerialConnection } from "./VexConnection.js";
|
|
3
4
|
import { VexEventTarget } from "./VexEvent.js";
|
|
@@ -6,7 +7,11 @@ import { type ProgramIniConfig } from "./VexIniConfig.js";
|
|
|
6
7
|
import { VexSerialError } from "./VexError.js";
|
|
7
8
|
import { ResultAsync } from "neverthrow";
|
|
8
9
|
import type { V5SerialDevice } from "./VexDevice.js";
|
|
9
|
-
export
|
|
10
|
+
export interface VexSerialDeviceEvents {
|
|
11
|
+
disconnected: undefined;
|
|
12
|
+
error: unknown;
|
|
13
|
+
}
|
|
14
|
+
export declare abstract class VexSerialDevice extends VexEventTarget<VexSerialDeviceEvents> {
|
|
10
15
|
connection: V5SerialConnection | undefined;
|
|
11
16
|
defaultSerial: Serial;
|
|
12
17
|
get isConnected(): boolean;
|
|
@@ -19,18 +24,24 @@ export declare class V5SerialDeviceState {
|
|
|
19
24
|
_instance: V5SerialDevice;
|
|
20
25
|
/**
|
|
21
26
|
* Counter used only to pause automatic refresh while a file transfer
|
|
22
|
-
* is in flight. This is not a mutex:
|
|
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.
|
|
27
|
+
* is in flight. This is not a mutex: serialization of transfer
|
|
28
|
+
* operations lives on the {@link V5SerialConnection} transaction queue.
|
|
26
29
|
*/
|
|
27
30
|
private refreshPauseDepth;
|
|
31
|
+
get isRefreshPaused(): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Use {@link isRefreshPaused}. This flag only means that
|
|
34
|
+
* automatic refresh is paused, not that transfer operations are locked.
|
|
35
|
+
*/
|
|
28
36
|
get isFileTransferring(): boolean;
|
|
29
37
|
/**
|
|
30
38
|
* Increment the refresh-pause depth, run the operation, and decrement
|
|
31
|
-
* the depth again. The actual transfer mutex lives on the connection
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
* the depth again. The actual transfer mutex lives on the connection.
|
|
40
|
+
*/
|
|
41
|
+
withRefreshPaused<T>(operation: () => PromiseLike<T>): Promise<T>;
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated Use {@link withRefreshPaused}. This only pauses automatic
|
|
44
|
+
* refresh and does not lock file transfers.
|
|
34
45
|
*/
|
|
35
46
|
withFileTransfer<T>(operation: () => PromiseLike<T>): Promise<T>;
|
|
36
47
|
brain: {
|
|
@@ -54,15 +65,18 @@ export declare class V5SerialDeviceState {
|
|
|
54
65
|
systemVersion: VexFirmwareVersion;
|
|
55
66
|
uniqueId: number;
|
|
56
67
|
};
|
|
57
|
-
controllers:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
controllers: [
|
|
69
|
+
{
|
|
70
|
+
battery: number;
|
|
71
|
+
isAvailable: boolean;
|
|
72
|
+
isCharging: boolean | undefined;
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
battery: number;
|
|
76
|
+
isAvailable: boolean;
|
|
77
|
+
isCharging: boolean | undefined;
|
|
78
|
+
}
|
|
79
|
+
];
|
|
66
80
|
devices: Array<ISmartDeviceInfo | undefined>;
|
|
67
81
|
isFieldControllerConnected: boolean;
|
|
68
82
|
matchMode: MatchMode;
|
|
@@ -80,6 +94,9 @@ export declare class V5SerialDeviceState {
|
|
|
80
94
|
}
|
|
81
95
|
export declare class V5Brain {
|
|
82
96
|
private readonly state;
|
|
97
|
+
private readonly batteryFacade;
|
|
98
|
+
private readonly buttonFacade;
|
|
99
|
+
private readonly settingsFacade;
|
|
83
100
|
constructor(state: V5SerialDeviceState);
|
|
84
101
|
get isRunningProgram(): boolean;
|
|
85
102
|
get activeProgram(): number;
|
|
@@ -160,6 +177,11 @@ export declare class V5Controller {
|
|
|
160
177
|
get batteryPercent(): number;
|
|
161
178
|
get isMasterController(): boolean;
|
|
162
179
|
get isAvailable(): boolean;
|
|
180
|
+
/**
|
|
181
|
+
* Whether the controller is charging. The V5 system-status response only
|
|
182
|
+
* reports this state for the primary controller, so the partner controller
|
|
183
|
+
* returns `undefined`.
|
|
184
|
+
*/
|
|
163
185
|
get isCharging(): boolean | undefined;
|
|
164
186
|
}
|
|
165
187
|
export declare class V5SmartDevice {
|
package/dist/VexError.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/// <reference types="dom-serial" preserve="true" />
|
|
2
|
+
import { type AckType } from "./Vex.js";
|
|
1
3
|
/**
|
|
2
4
|
* Typed error hierarchy for the serial protocol package.
|
|
3
5
|
*
|
|
@@ -10,6 +12,7 @@ export type VexSerialErrorKind = "not-connected" | "invalid-argument" | "protoco
|
|
|
10
12
|
/** Base class for every failure surfaced by the serial package. */
|
|
11
13
|
export declare class VexSerialError extends Error {
|
|
12
14
|
readonly kind: VexSerialErrorKind;
|
|
15
|
+
readonly ackType: AckType | undefined;
|
|
13
16
|
constructor(kind: VexSerialErrorKind, message: string);
|
|
14
17
|
}
|
|
15
18
|
/** No connection is currently open to a device. */
|
|
@@ -22,7 +25,8 @@ export declare class VexInvalidArgumentError extends VexSerialError {
|
|
|
22
25
|
}
|
|
23
26
|
/** The device refused, timed out, or replied unexpectedly to a command. */
|
|
24
27
|
export declare class VexProtocolError extends VexSerialError {
|
|
25
|
-
|
|
28
|
+
readonly ackType: AckType | undefined;
|
|
29
|
+
constructor(message: string, ackType?: AckType);
|
|
26
30
|
}
|
|
27
31
|
/** A file-transfer handshake, read, write, or exit failed. */
|
|
28
32
|
export declare class VexTransferError extends VexSerialError {
|
package/dist/VexEvent.d.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type EventName = string | symbol;
|
|
2
|
+
type EventMapKey<TEvents> = Extract<keyof TEvents, EventName>;
|
|
3
|
+
type EventListener<TValue> = (data: TValue) => void;
|
|
4
|
+
export declare class VexEventEmitter<TEvents extends object = Record<EventName, unknown>> {
|
|
5
|
+
handlerMap: Map<EventName, Array<EventListener<unknown>>>;
|
|
3
6
|
constructor();
|
|
4
|
-
on(eventName:
|
|
5
|
-
remove(eventName:
|
|
6
|
-
emit(eventName:
|
|
7
|
+
on<K extends EventMapKey<TEvents>>(eventName: K, listener: EventListener<TEvents[K]>): void;
|
|
8
|
+
remove<K extends EventMapKey<TEvents>>(eventName: K, listener: EventListener<TEvents[K]>): void;
|
|
9
|
+
emit<K extends EventMapKey<TEvents>>(eventName: K, data: TEvents[K]): void;
|
|
7
10
|
clearListeners(): void;
|
|
8
11
|
}
|
|
9
|
-
export declare class VexEventTarget {
|
|
10
|
-
emitter: VexEventEmitter
|
|
12
|
+
export declare class VexEventTarget<TEvents extends object = Record<EventName, unknown>> {
|
|
13
|
+
emitter: VexEventEmitter<TEvents>;
|
|
11
14
|
constructor();
|
|
12
|
-
emit(eventName:
|
|
13
|
-
on(eventName:
|
|
14
|
-
remove(eventName:
|
|
15
|
+
emit<K extends EventMapKey<TEvents>>(eventName: K, data: TEvents[K]): void;
|
|
16
|
+
on<K extends EventMapKey<TEvents>>(eventName: K, listener: EventListener<TEvents[K]>): void;
|
|
17
|
+
remove<K extends EventMapKey<TEvents>>(eventName: K, listener: EventListener<TEvents[K]>): void;
|
|
15
18
|
clearListeners(): void;
|
|
16
19
|
}
|
|
20
|
+
export {};
|
package/dist/VexFirmware.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="dom-serial" preserve="true" />
|
|
1
2
|
import type { V5SerialDeviceState } from "./VexDeviceState.js";
|
|
2
3
|
import { VexSerialError } from "./VexError.js";
|
|
3
4
|
import { ResultAsync } from "neverthrow";
|
|
@@ -36,10 +37,12 @@ export declare function sleepUntil(f: () => boolean, timeout: number, interval?:
|
|
|
36
37
|
* when `ms` is negative.
|
|
37
38
|
*/
|
|
38
39
|
export declare function sleep(ms: number): ResultAsync<void, VexSerialError>;
|
|
40
|
+
type FirmwareProgressCallback = (state: string, current: number, total: number) => void;
|
|
39
41
|
/**
|
|
40
42
|
* Upload a VEXos firmware archive to a connected brain. Network and
|
|
41
43
|
* archive validation failures are returned as {@link VexSerialError}
|
|
42
44
|
* values rather than thrown; a device that refuses a step or a missing
|
|
43
|
-
* connection surfaces as {@link
|
|
45
|
+
* connection surfaces as {@link VexFirmwareError} / {@link VexNotConnectedError}.
|
|
44
46
|
*/
|
|
45
|
-
export declare function uploadFirmware(state: V5SerialDeviceState, publicUrl?: string, usingVersion?: string, progressCallback?:
|
|
47
|
+
export declare function uploadFirmware(state: V5SerialDeviceState, publicUrl?: string, usingVersion?: string, progressCallback?: FirmwareProgressCallback): ResultAsync<boolean, VexSerialError>;
|
|
48
|
+
export {};
|
|
@@ -1,55 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This is a class to make it easier to handle passing the VEXos version
|
|
3
|
-
* information around in the application. This provides ways to get any
|
|
4
|
-
* form of the string representation and quickly compare versions.
|
|
5
|
-
*/
|
|
6
1
|
export declare class VexFirmwareVersion {
|
|
7
|
-
major: number;
|
|
8
|
-
minor: number;
|
|
9
|
-
build: number;
|
|
10
|
-
beta: number;
|
|
2
|
+
readonly major: number;
|
|
3
|
+
readonly minor: number;
|
|
4
|
+
readonly build: number;
|
|
5
|
+
readonly beta: number;
|
|
11
6
|
constructor(major: number, minor: number, build: number, beta: number);
|
|
12
|
-
/**
|
|
13
|
-
* Take a a string of MAJOR.MINOR.BUILD.bBETA and converts it to a
|
|
14
|
-
* VexFirmwareVersion instance
|
|
15
|
-
* @param version the string to process
|
|
16
|
-
* @returns a VexFirmwareVersion representing the provided string
|
|
17
|
-
*/
|
|
18
7
|
static fromString(version: string): VexFirmwareVersion;
|
|
19
|
-
/**
|
|
20
|
-
* Take a a Uint8Array and converts it to a VexFirmwareVersion instance
|
|
21
|
-
* @param data the array to process
|
|
22
|
-
* @param offset the offset to start at
|
|
23
|
-
* @returns a VexFirmwareVersion representing the provided string
|
|
24
|
-
*/
|
|
25
8
|
static fromUint8Array(data: Uint8Array, offset?: number, reverse?: boolean): VexFirmwareVersion;
|
|
26
9
|
static allZero(): VexFirmwareVersion;
|
|
27
|
-
/**
|
|
28
|
-
* Take a a string of MAJOR_MINOR_BUILD_BETA and converts it to a
|
|
29
|
-
* VexFirmwareVersion instance
|
|
30
|
-
* @param version the string to process
|
|
31
|
-
* @returns a VexFirmwareVersion representing the provided string
|
|
32
|
-
*/
|
|
33
10
|
static fromCatalogString(version: string): VexFirmwareVersion;
|
|
34
11
|
isBeta(): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* returns version as Uint Array
|
|
37
|
-
*/
|
|
38
12
|
toUint8Array(reverse?: boolean): Uint8Array;
|
|
39
|
-
/**
|
|
40
|
-
* returns version as major.minor.build
|
|
41
|
-
*/
|
|
42
13
|
toUserString(): string;
|
|
43
|
-
/**
|
|
44
|
-
* returns version as ${major}.${minor}.{build}.b${beta}
|
|
45
|
-
*/
|
|
46
14
|
toInternalString(): string;
|
|
47
|
-
/**
|
|
48
|
-
* compares this version to the provided version.
|
|
49
|
-
* * if this < b: negative
|
|
50
|
-
* * if this = b: 0
|
|
51
|
-
* * if this > b: positive
|
|
52
|
-
* @param that the version to compare again
|
|
53
|
-
*/
|
|
54
15
|
compare(that: VexFirmwareVersion): number;
|
|
55
16
|
}
|
package/dist/VexIniConfig.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export declare class ProgramIniConfig {
|
|
|
20
20
|
config: Record<number, string>;
|
|
21
21
|
controller1: Record<string, string>;
|
|
22
22
|
controller2: Record<string, string>;
|
|
23
|
-
constructor();
|
|
24
23
|
setProgramDate(date: Date): void;
|
|
25
24
|
createIni(): string;
|
|
26
25
|
dec2(value: number): string;
|
package/dist/VexPacketBase.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import { AckType, type DataArray } from "./Vex.js";
|
|
2
2
|
import type { PacketEncoder } from "./VexPacketEncoder.js";
|
|
3
3
|
export declare abstract class Packet {
|
|
4
|
+
/** Raw bytes sent to or received from the device. */
|
|
4
5
|
data: Uint8Array;
|
|
5
6
|
static ENCODER: PacketEncoder;
|
|
6
7
|
constructor(rawData: DataArray);
|
|
7
8
|
}
|
|
8
9
|
export declare class DeviceBoundPacket extends Packet {
|
|
9
|
-
get commandId(): number;
|
|
10
|
-
get commandExtendedId(): number | undefined;
|
|
11
10
|
static COMMAND_ID: number;
|
|
12
11
|
static COMMAND_EXTENDED_ID: number | undefined;
|
|
12
|
+
get commandId(): number;
|
|
13
|
+
get commandExtendedId(): number | undefined;
|
|
13
14
|
constructor(payload?: Uint8Array);
|
|
14
15
|
}
|
|
15
16
|
export declare class HostBoundPacket extends Packet {
|
|
17
|
+
static COMMAND_ID: number;
|
|
18
|
+
static COMMAND_EXTENDED_ID: number | undefined;
|
|
16
19
|
ack: AckType;
|
|
17
20
|
payloadSize: number;
|
|
18
21
|
ackIndex: number;
|
|
@@ -8,46 +8,29 @@ export declare class PacketEncoder {
|
|
|
8
8
|
static J2000_EPOCH: number;
|
|
9
9
|
vexVersion: number;
|
|
10
10
|
crcgen: CrcGenerator;
|
|
11
|
-
allPacketsTable:
|
|
11
|
+
allPacketsTable: Map<number, Map<number | undefined, typeof HostBoundPacket>>;
|
|
12
12
|
static getInstance(): PacketEncoder;
|
|
13
13
|
private constructor();
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
/** Register reply packet classes without retaining an entire module object. */
|
|
15
|
+
registerPacketTypes(types: Iterable<typeof HostBoundPacket>): void;
|
|
16
|
+
/** Look up the reply class registered for a command ID pair. */
|
|
17
|
+
getPacketType(commandId: number | undefined, commandExtendedId: number | undefined): typeof HostBoundPacket | undefined;
|
|
18
|
+
/** Create the vex CDC header. */
|
|
18
19
|
createHeader(buf: ArrayBuffer | undefined): Uint8Array;
|
|
19
|
-
/**
|
|
20
|
-
* Create the vex CDC simple message
|
|
21
|
-
* @param cmd the CDC command byte
|
|
22
|
-
*/
|
|
20
|
+
/** Create a simple CDC message. */
|
|
23
21
|
cdcCommand(cmd: number): Uint8Array;
|
|
24
|
-
/**
|
|
25
|
-
* Create the vex CDC simple message
|
|
26
|
-
* @param cmd the CDC command byte
|
|
27
|
-
* @param data the data to send
|
|
28
|
-
*/
|
|
22
|
+
/** Create a simple CDC message carrying data. */
|
|
29
23
|
cdcCommandWithData(cmd: number, data: Uint8Array): Uint8Array;
|
|
30
|
-
/**
|
|
31
|
-
* Create the vex CDC extended message
|
|
32
|
-
* @param cmd the CDC command byte
|
|
33
|
-
* @param ext the CDC extended command byte
|
|
34
|
-
* @return a message
|
|
35
|
-
*/
|
|
24
|
+
/** Create a CDC2 (extended) message with no payload. */
|
|
36
25
|
cdc2Command(cmd: number, ext: number): Uint8Array;
|
|
37
26
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @returns the required buffer length of the command message
|
|
27
|
+
* Buffer length for a CDC2 command: header + command byte + function
|
|
28
|
+
* byte + length byte (two bytes when payload > 127) + payload + CRC16.
|
|
41
29
|
*/
|
|
42
30
|
cdc2CommandBufferLength(data: Uint8Array): number;
|
|
43
|
-
/**
|
|
44
|
-
* Create the vex CDC extended message with some data
|
|
45
|
-
* @param cmd the CDC command byte
|
|
46
|
-
* @param ext the CDC extended command byte
|
|
47
|
-
* @param data the CDC extended command payload
|
|
48
|
-
* @return a message
|
|
49
|
-
*/
|
|
31
|
+
/** Create a CDC2 (extended) message carrying a payload. */
|
|
50
32
|
cdc2CommandWithData(cmd: number, ext: number, data: Uint8Array): Uint8Array;
|
|
33
|
+
private appendCrc16;
|
|
51
34
|
validateHeader(data: Uint8Array): boolean;
|
|
52
35
|
validateMessageCdc(data: Uint8Array): boolean;
|
|
53
36
|
getPayloadSize(data: Uint8Array): number;
|