react-native-web-serial-api 0.0.3 → 0.2.0
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 +198 -104
- package/TESTING.md +542 -0
- package/android/build.gradle +16 -2
- package/android/src/main/java/dev/webserialapi/NativeUsbSerialModule.java +74 -11
- package/android/src/main/java/dev/webserialapi/PortPickerActivity.java +61 -59
- package/bin/expose-serial.js +205 -0
- package/lib/commonjs/UsbSerial.js +58 -26
- package/lib/commonjs/UsbSerial.js.map +1 -1
- package/lib/commonjs/WebSerial.js +273 -77
- package/lib/commonjs/WebSerial.js.map +1 -1
- package/lib/commonjs/index.js +15 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/lib/dom-exception.js +176 -0
- package/lib/commonjs/lib/dom-exception.js.map +1 -0
- package/lib/commonjs/lib/event-target.js +140 -0
- package/lib/commonjs/lib/event-target.js.map +1 -0
- package/lib/commonjs/lib/promise.js +23 -0
- package/lib/commonjs/lib/promise.js.map +1 -0
- package/lib/commonjs/lib/web-streams.js +42 -0
- package/lib/commonjs/lib/web-streams.js.map +1 -0
- package/lib/commonjs/testing/device-fixture.js +70 -0
- package/lib/commonjs/testing/device-fixture.js.map +1 -0
- package/lib/commonjs/testing/expose.js +91 -0
- package/lib/commonjs/testing/expose.js.map +1 -0
- package/lib/commonjs/testing/harness.js +98 -0
- package/lib/commonjs/testing/harness.js.map +1 -0
- package/lib/commonjs/testing/in-memory-serial-transport.js +653 -0
- package/lib/commonjs/testing/in-memory-serial-transport.js.map +1 -0
- package/lib/commonjs/testing/index.js +153 -0
- package/lib/commonjs/testing/index.js.map +1 -0
- package/lib/commonjs/testing/install-in-memory-serial-transport.js +54 -0
- package/lib/commonjs/testing/install-in-memory-serial-transport.js.map +1 -0
- package/lib/commonjs/testing/serial-client.js +277 -0
- package/lib/commonjs/testing/serial-client.js.map +1 -0
- package/lib/commonjs/testing/simulated-device.js +164 -0
- package/lib/commonjs/testing/simulated-device.js.map +1 -0
- package/lib/commonjs/testing/test-suite.js +142 -0
- package/lib/commonjs/testing/test-suite.js.map +1 -0
- package/lib/commonjs/transport.js +61 -0
- package/lib/commonjs/transport.js.map +1 -0
- package/lib/commonjs/websocket/WebSocketSerialTransport.js +659 -0
- package/lib/commonjs/websocket/WebSocketSerialTransport.js.map +1 -0
- package/lib/commonjs/websocket/bridge.js +234 -0
- package/lib/commonjs/websocket/bridge.js.map +1 -0
- package/lib/commonjs/websocket/index.js +33 -0
- package/lib/commonjs/websocket/index.js.map +1 -0
- package/lib/commonjs/websocket/protocol.js +55 -0
- package/lib/commonjs/websocket/protocol.js.map +1 -0
- package/lib/commonjs/websocket/serial-device-bridge.js +130 -0
- package/lib/commonjs/websocket/serial-device-bridge.js.map +1 -0
- package/lib/typescript/src/UsbSerial.d.ts +24 -67
- package/lib/typescript/src/UsbSerial.d.ts.map +1 -1
- package/lib/typescript/src/WebSerial.d.ts +16 -7
- package/lib/typescript/src/WebSerial.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/lib/dom-exception.d.ts +100 -0
- package/lib/typescript/src/lib/dom-exception.d.ts.map +1 -0
- package/lib/typescript/src/lib/event-target.d.ts +55 -0
- package/lib/typescript/src/lib/event-target.d.ts.map +1 -0
- package/lib/typescript/src/lib/promise.d.ts +11 -0
- package/lib/typescript/src/lib/promise.d.ts.map +1 -0
- package/lib/typescript/src/lib/web-streams.d.ts +9 -0
- package/lib/typescript/src/lib/web-streams.d.ts.map +1 -0
- package/lib/typescript/src/testing/device-fixture.d.ts +70 -0
- package/lib/typescript/src/testing/device-fixture.d.ts.map +1 -0
- package/lib/typescript/src/testing/expose.d.ts +71 -0
- package/lib/typescript/src/testing/expose.d.ts.map +1 -0
- package/lib/typescript/src/testing/harness.d.ts +34 -0
- package/lib/typescript/src/testing/harness.d.ts.map +1 -0
- package/lib/typescript/src/testing/in-memory-serial-transport.d.ts +216 -0
- package/lib/typescript/src/testing/in-memory-serial-transport.d.ts.map +1 -0
- package/lib/typescript/src/testing/index.d.ts +33 -0
- package/lib/typescript/src/testing/index.d.ts.map +1 -0
- package/lib/typescript/src/testing/install-in-memory-serial-transport.d.ts +25 -0
- package/lib/typescript/src/testing/install-in-memory-serial-transport.d.ts.map +1 -0
- package/lib/typescript/src/testing/serial-client.d.ts +62 -0
- package/lib/typescript/src/testing/serial-client.d.ts.map +1 -0
- package/lib/typescript/src/testing/simulated-device.d.ts +127 -0
- package/lib/typescript/src/testing/simulated-device.d.ts.map +1 -0
- package/lib/typescript/src/testing/test-suite.d.ts +75 -0
- package/lib/typescript/src/testing/test-suite.d.ts.map +1 -0
- package/lib/typescript/src/transport.d.ts +131 -0
- package/lib/typescript/src/transport.d.ts.map +1 -0
- package/lib/typescript/src/websocket/WebSocketSerialTransport.d.ts +111 -0
- package/lib/typescript/src/websocket/WebSocketSerialTransport.d.ts.map +1 -0
- package/lib/typescript/src/websocket/bridge.d.ts +66 -0
- package/lib/typescript/src/websocket/bridge.d.ts.map +1 -0
- package/lib/typescript/src/websocket/index.d.ts +19 -0
- package/lib/typescript/src/websocket/index.d.ts.map +1 -0
- package/lib/typescript/src/websocket/protocol.d.ts +64 -0
- package/lib/typescript/src/websocket/protocol.d.ts.map +1 -0
- package/lib/typescript/src/websocket/serial-device-bridge.d.ts +32 -0
- package/lib/typescript/src/websocket/serial-device-bridge.d.ts.map +1 -0
- package/package.json +57 -3
- package/src/UsbSerial.ts +65 -90
- package/src/WebSerial.ts +351 -113
- package/src/index.ts +6 -8
- package/src/lib/dom-exception.ts +129 -60
- package/src/lib/event-target.ts +58 -21
- package/src/lib/promise.ts +7 -7
- package/src/lib/web-streams.ts +43 -0
- package/src/testing/device-fixture.ts +150 -0
- package/src/testing/expose.ts +147 -0
- package/src/testing/harness.ts +124 -0
- package/src/testing/in-memory-serial-transport.ts +840 -0
- package/src/testing/index.ts +90 -0
- package/src/testing/install-in-memory-serial-transport.ts +65 -0
- package/src/testing/serial-client.ts +313 -0
- package/src/testing/simulated-device.ts +193 -0
- package/src/testing/test-suite.ts +186 -0
- package/src/transport.ts +200 -0
- package/src/websocket/WebSocketSerialTransport.ts +796 -0
- package/src/websocket/bridge.ts +299 -0
- package/src/websocket/index.ts +38 -0
- package/src/websocket/protocol.ts +101 -0
- package/src/websocket/serial-device-bridge.ts +160 -0
- package/babel.config.js +0 -3
- package/biome.json +0 -35
- package/example/.watchmanconfig +0 -1
- package/example/App.tsx +0 -71
- package/example/__tests__/App.test.tsx +0 -16
- package/example/__tests__/connectEvents.test.tsx +0 -81
- package/example/__tests__/getPorts.test.tsx +0 -140
- package/example/android/app/build.gradle +0 -120
- package/example/android/app/debug.keystore +0 -0
- package/example/android/app/proguard-rules.pro +0 -10
- package/example/android/app/src/debug/AndroidManifest.xml +0 -9
- package/example/android/app/src/main/AndroidManifest.xml +0 -38
- package/example/android/app/src/main/java/dev/uzlopak/MainActivity.kt +0 -22
- package/example/android/app/src/main/java/dev/uzlopak/MainApplication.kt +0 -41
- package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -37
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- package/example/android/app/src/main/res/values/strings.xml +0 -3
- package/example/android/app/src/main/res/values/styles.xml +0 -9
- package/example/android/build.gradle +0 -22
- package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/example/android/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/example/android/gradle.properties +0 -47
- package/example/android/gradlew +0 -252
- package/example/android/gradlew.bat +0 -94
- package/example/android/settings.gradle +0 -6
- package/example/app.json +0 -4
- package/example/babel.config.js +0 -21
- package/example/biome.json +0 -47
- package/example/deploy.sh +0 -11
- package/example/index.html +0 -26
- package/example/index.js +0 -9
- package/example/index.web.js +0 -8
- package/example/jest.config.js +0 -12
- package/example/metro.config.js +0 -58
- package/example/package-lock.json +0 -14510
- package/example/package.json +0 -48
- package/example/react-native.config.js +0 -17
- package/example/src/components/AppBar.tsx +0 -73
- package/example/src/components/Menu.tsx +0 -90
- package/example/src/components/SingleChoiceDialog.tsx +0 -120
- package/example/src/screens/ConnectScreen.tsx +0 -195
- package/example/src/screens/DevicesScreen.tsx +0 -252
- package/example/src/screens/TerminalScreen.tsx +0 -572
- package/example/src/settings.ts +0 -43
- package/example/src/theme.ts +0 -19
- package/example/src/util/TextUtil.ts +0 -129
- package/example/tsconfig.json +0 -10
- package/example/vite.config.mjs +0 -55
- package/scripts/deploy-release.sh +0 -127
- package/tsconfig.build.json +0 -7
- package/tsconfig.json +0 -20
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hardware-transport abstraction for the Web Serial polyfill.
|
|
3
|
+
*
|
|
4
|
+
* `SerialTransport` is the single interface that the `Serial`/`SerialPort`
|
|
5
|
+
* classes depend on to talk to "the device". The production implementation
|
|
6
|
+
* (`UsbSerialModule`, backed by the `NativeUsbSerial` TurboModule — see
|
|
7
|
+
* {@link ./UsbSerial}) and the in-memory test/dev double
|
|
8
|
+
* (`InMemorySerialTransport` — see {@link ./testing/in-memory-serial-transport}) both
|
|
9
|
+
* implement it.
|
|
10
|
+
*
|
|
11
|
+
* This module is intentionally free of any `react-native` import. That is what
|
|
12
|
+
* lets the virtual transport — and therefore the conformance suite built on top
|
|
13
|
+
* of it — run unchanged under Node/Jest, in a browser, and on a device.
|
|
14
|
+
*/
|
|
15
|
+
export type ControlLine = 'RTS' | 'CTS' | 'DTR' | 'DSR' | 'CD' | 'RI';
|
|
16
|
+
export type FlowControl = 'NONE' | 'RTS_CTS' | 'DTR_DSR' | 'XON_XOFF' | 'XON_XOFF_INLINE';
|
|
17
|
+
export type PortFilter = {
|
|
18
|
+
usbVendorId?: number;
|
|
19
|
+
usbProductId?: number;
|
|
20
|
+
};
|
|
21
|
+
export type PortPickerLabels = {
|
|
22
|
+
titleSelectPort?: string;
|
|
23
|
+
titleNoPortsAvailable?: string;
|
|
24
|
+
messageNoPortsAvailable?: string;
|
|
25
|
+
};
|
|
26
|
+
export type PortId = {
|
|
27
|
+
deviceId: number;
|
|
28
|
+
portNumber: number;
|
|
29
|
+
usbVendorId: number;
|
|
30
|
+
usbProductId: number;
|
|
31
|
+
/**
|
|
32
|
+
* Whether the app currently holds Android USB permission to access this
|
|
33
|
+
* device (via the system attach dialog or a prior permission request).
|
|
34
|
+
*/
|
|
35
|
+
hasPermission: boolean;
|
|
36
|
+
};
|
|
37
|
+
export type DataEvent = {
|
|
38
|
+
deviceId: number;
|
|
39
|
+
portNumber: number;
|
|
40
|
+
data: number[];
|
|
41
|
+
};
|
|
42
|
+
export type ErrorEvent = {
|
|
43
|
+
deviceId: number;
|
|
44
|
+
portNumber: number;
|
|
45
|
+
error: string;
|
|
46
|
+
/**
|
|
47
|
+
* Optional spec error name (e.g. "BreakError", "BufferOverrunError",
|
|
48
|
+
* "FramingError", "ParityError") for a typed read error. When present the
|
|
49
|
+
* polyfill surfaces a DOMException of that name on the readable stream
|
|
50
|
+
* (otherwise it defaults to "NetworkError"); the WPT-derived spec tests in
|
|
51
|
+
* src/__tests__/conformance-suite.ts exercise this (BreakError,
|
|
52
|
+
* BufferOverrunError).
|
|
53
|
+
*/
|
|
54
|
+
errorName?: string;
|
|
55
|
+
};
|
|
56
|
+
export type ConnectEvent = {
|
|
57
|
+
deviceId: number;
|
|
58
|
+
usbVendorId: number;
|
|
59
|
+
usbProductId: number;
|
|
60
|
+
};
|
|
61
|
+
export declare const Parity: {
|
|
62
|
+
readonly NONE: 0;
|
|
63
|
+
readonly ODD: 1;
|
|
64
|
+
readonly EVEN: 2;
|
|
65
|
+
readonly MARK: 3;
|
|
66
|
+
readonly SPACE: 4;
|
|
67
|
+
};
|
|
68
|
+
export declare const DataBits: {
|
|
69
|
+
readonly FIVE: 5;
|
|
70
|
+
readonly SIX: 6;
|
|
71
|
+
readonly SEVEN: 7;
|
|
72
|
+
readonly EIGHT: 8;
|
|
73
|
+
};
|
|
74
|
+
export declare const StopBits: {
|
|
75
|
+
readonly ONE: 1;
|
|
76
|
+
readonly ONE_FIVE: 3;
|
|
77
|
+
readonly TWO: 2;
|
|
78
|
+
};
|
|
79
|
+
export type OpenOptions = {
|
|
80
|
+
baudRate: number;
|
|
81
|
+
dataBits?: number;
|
|
82
|
+
stopBits?: number;
|
|
83
|
+
parity?: number;
|
|
84
|
+
};
|
|
85
|
+
export declare const DEFAULT_OPEN_OPTIONS: Required<Omit<OpenOptions, 'baudRate'>>;
|
|
86
|
+
/** Handle returned by the `on*` subscription methods. */
|
|
87
|
+
export type Subscription = {
|
|
88
|
+
remove: () => void;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* The contract every serial transport must satisfy. It mirrors the JS-friendly
|
|
92
|
+
* surface of `UsbSerialModule` exactly, so `UsbSerialModule implements
|
|
93
|
+
* SerialTransport` is a faithful 1:1 and any conforming double (e.g.
|
|
94
|
+
* `InMemorySerialTransport`) is a drop-in replacement.
|
|
95
|
+
*
|
|
96
|
+
* Ports are addressed by the pair `(deviceId, portNumber)`. Inbound bytes,
|
|
97
|
+
* read errors and device attach/detach arrive through the `on*` subscriptions.
|
|
98
|
+
*/
|
|
99
|
+
export interface SerialTransport {
|
|
100
|
+
findAllDrivers(): Promise<ReadonlyArray<PortId>>;
|
|
101
|
+
showPortPicker(filter: ReadonlyArray<PortFilter>, labels?: PortPickerLabels): Promise<PortId>;
|
|
102
|
+
requestPermission(deviceId: number): Promise<boolean>;
|
|
103
|
+
open(deviceId: number, portNumber: number, options: OpenOptions): Promise<void>;
|
|
104
|
+
close(deviceId: number, portNumber: number): Promise<void>;
|
|
105
|
+
isOpen(deviceId: number, portNumber: number): boolean;
|
|
106
|
+
write(deviceId: number, portNumber: number, data: number[], timeout?: number): Promise<void>;
|
|
107
|
+
startReading(deviceId: number, portNumber: number): Promise<void>;
|
|
108
|
+
stopReading(deviceId: number, portNumber: number): Promise<void>;
|
|
109
|
+
setParameters(deviceId: number, portNumber: number, options: OpenOptions): Promise<void>;
|
|
110
|
+
setDTR(deviceId: number, portNumber: number, value: boolean): Promise<void>;
|
|
111
|
+
setRTS(deviceId: number, portNumber: number, value: boolean): Promise<void>;
|
|
112
|
+
getDTR(deviceId: number, portNumber: number): Promise<boolean>;
|
|
113
|
+
getRTS(deviceId: number, portNumber: number): Promise<boolean>;
|
|
114
|
+
getCD(deviceId: number, portNumber: number): Promise<boolean>;
|
|
115
|
+
getCTS(deviceId: number, portNumber: number): Promise<boolean>;
|
|
116
|
+
getDSR(deviceId: number, portNumber: number): Promise<boolean>;
|
|
117
|
+
getRI(deviceId: number, portNumber: number): Promise<boolean>;
|
|
118
|
+
getControlLines(deviceId: number, portNumber: number): Promise<ControlLine[]>;
|
|
119
|
+
getSupportedControlLines(deviceId: number, portNumber: number): Promise<ControlLine[]>;
|
|
120
|
+
setFlowControl(deviceId: number, portNumber: number, flowControl: FlowControl): Promise<void>;
|
|
121
|
+
getFlowControl(deviceId: number, portNumber: number): Promise<FlowControl>;
|
|
122
|
+
getSupportedFlowControl(deviceId: number, portNumber: number): Promise<FlowControl[]>;
|
|
123
|
+
setBreak(deviceId: number, portNumber: number, value: boolean): Promise<void>;
|
|
124
|
+
purgeHwBuffers(deviceId: number, portNumber: number, purgeWriteBuffers: boolean, purgeReadBuffers: boolean): Promise<void>;
|
|
125
|
+
getSerial(deviceId: number, portNumber: number): Promise<string>;
|
|
126
|
+
onData(listener: (event: DataEvent) => void): Subscription;
|
|
127
|
+
onError(listener: (event: ErrorEvent) => void): Subscription;
|
|
128
|
+
onConnect(listener: (event: ConnectEvent) => void): Subscription;
|
|
129
|
+
onDisconnect(listener: (event: ConnectEvent) => void): Subscription;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A {@link SerialTransport} that talks to a remote serial port over a WebSocket
|
|
3
|
+
* bridge (run `expose-serial-websocket` on the host — see `bin/expose-serial.js`).
|
|
4
|
+
*
|
|
5
|
+
* Because it implements the same transport contract as the native `UsbSerialModule` and the
|
|
6
|
+
* in-memory `InMemorySerialTransport`, it's a drop-in: the whole `Serial` /
|
|
7
|
+
* `SerialPort` polyfill (streams, signals, reconnect, the conformance suite)
|
|
8
|
+
* works on top of it unchanged.
|
|
9
|
+
*
|
|
10
|
+
* **Resilience.** The socket is supervised: an unexpected drop (server restart,
|
|
11
|
+
* network blip) is handled transparently — the transport reconnects with
|
|
12
|
+
* exponential backoff and *restores the session* (line coding, control signals,
|
|
13
|
+
* and read state) so the app's open `SerialPort` keeps working. A transient
|
|
14
|
+
* drop is therefore invisible to the polyfill (reads pause and resume; writes
|
|
15
|
+
* issued during the gap wait for the reconnection). Only a real remote
|
|
16
|
+
* disconnect (the host's serial port going away) or giving up after
|
|
17
|
+
* `maxReconnectAttempts` surfaces as a serial disconnect.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* import {Serial} from 'react-native-web-serial-api';
|
|
21
|
+
* import {WebSocketSerialTransport} from 'react-native-web-serial-api/websocket';
|
|
22
|
+
*
|
|
23
|
+
* const serial = new Serial(new WebSocketSerialTransport('ws://localhost:8080'));
|
|
24
|
+
* const [port] = await serial.getPorts();
|
|
25
|
+
* await port.open({baudRate: 115200});
|
|
26
|
+
*/
|
|
27
|
+
import type { ConnectEvent, ControlLine, DataEvent, ErrorEvent, FlowControl, OpenOptions, PortFilter, PortId, PortPickerLabels, SerialTransport, Subscription } from '../transport';
|
|
28
|
+
/** Minimal structural WebSocket shape (browser & React Native both provide it). */
|
|
29
|
+
export interface WebSocketLike {
|
|
30
|
+
binaryType: string;
|
|
31
|
+
send(data: string | ArrayBufferLike | ArrayBufferView): void;
|
|
32
|
+
close(): void;
|
|
33
|
+
addEventListener(type: string, listener: (event: {
|
|
34
|
+
data?: unknown;
|
|
35
|
+
}) => void): void;
|
|
36
|
+
}
|
|
37
|
+
export type WebSocketCtor = new (url: string) => WebSocketLike;
|
|
38
|
+
export type WebSocketConnectionState = 'connecting' | 'open' | 'reconnecting' | 'suspended' | 'closed';
|
|
39
|
+
export type WebSocketSerialOptions = {
|
|
40
|
+
/** USB identity to report from getInfo() (cosmetic; default 0/0). */
|
|
41
|
+
usbVendorId?: number;
|
|
42
|
+
usbProductId?: number;
|
|
43
|
+
/** Serial number returned by getSerial(). */
|
|
44
|
+
serialNumber?: string;
|
|
45
|
+
/** WebSocket implementation (defaults to the global). Injectable for tests. */
|
|
46
|
+
WebSocket?: WebSocketCtor;
|
|
47
|
+
/** Auto-reconnect when the socket drops unexpectedly. Default `true`. */
|
|
48
|
+
reconnect?: boolean;
|
|
49
|
+
/** Initial reconnect backoff in ms; doubles each attempt. Default 250. */
|
|
50
|
+
reconnectInitialDelayMs?: number;
|
|
51
|
+
/** Cap on the reconnect backoff in ms. Default 10000. */
|
|
52
|
+
reconnectMaxDelayMs?: number;
|
|
53
|
+
/** Give up (surface a disconnect) after this many consecutive failures. Default Infinity. */
|
|
54
|
+
maxReconnectAttempts?: number;
|
|
55
|
+
/** How long write()/commands wait for a (re)connection before failing. Default 10000. */
|
|
56
|
+
connectTimeoutMs?: number;
|
|
57
|
+
/** How long a control command waits for its response before failing. Default 10000. */
|
|
58
|
+
commandTimeoutMs?: number;
|
|
59
|
+
/** Notified before each reconnect attempt (1-based attempt + the chosen delay). */
|
|
60
|
+
onReconnecting?: (attempt: number, delayMs: number) => void;
|
|
61
|
+
/** Notified once (re)connected; `reconnected` is false only for the first connect. */
|
|
62
|
+
onConnected?: (info: {
|
|
63
|
+
reconnected: boolean;
|
|
64
|
+
}) => void;
|
|
65
|
+
/** Notified when the transport is permanently closed (gave up, or `disconnect()`). */
|
|
66
|
+
onClosed?: (reason: string) => void;
|
|
67
|
+
};
|
|
68
|
+
type Listener<E> = (event: E) => void;
|
|
69
|
+
export declare class WebSocketSerialTransport implements SerialTransport {
|
|
70
|
+
#private;
|
|
71
|
+
constructor(url: string, options?: WebSocketSerialOptions);
|
|
72
|
+
/** Current connection state (advisory; the polyfill keeps working across reconnects). */
|
|
73
|
+
get connectionState(): WebSocketConnectionState;
|
|
74
|
+
findAllDrivers(): Promise<ReadonlyArray<PortId>>;
|
|
75
|
+
showPortPicker(_filter: ReadonlyArray<PortFilter>, _labels?: PortPickerLabels): Promise<PortId>;
|
|
76
|
+
requestPermission(_deviceId: number): Promise<boolean>;
|
|
77
|
+
open(_deviceId: number, _portNumber: number, options: OpenOptions): Promise<void>;
|
|
78
|
+
close(_deviceId: number, _portNumber: number): Promise<void>;
|
|
79
|
+
isOpen(_deviceId: number, _portNumber: number): boolean;
|
|
80
|
+
write(_deviceId: number, _portNumber: number, data: number[], _timeout?: number): Promise<void>;
|
|
81
|
+
startReading(_deviceId: number, _portNumber: number): Promise<void>;
|
|
82
|
+
stopReading(_deviceId: number, _portNumber: number): Promise<void>;
|
|
83
|
+
setParameters(_deviceId: number, _portNumber: number, options: OpenOptions): Promise<void>;
|
|
84
|
+
setDTR(_d: number, _p: number, value: boolean): Promise<void>;
|
|
85
|
+
setRTS(_d: number, _p: number, value: boolean): Promise<void>;
|
|
86
|
+
getDTR(_d: number, _p: number): Promise<boolean>;
|
|
87
|
+
getRTS(_d: number, _p: number): Promise<boolean>;
|
|
88
|
+
getCD(_d: number, _p: number): Promise<boolean>;
|
|
89
|
+
getCTS(_d: number, _p: number): Promise<boolean>;
|
|
90
|
+
getDSR(_d: number, _p: number): Promise<boolean>;
|
|
91
|
+
getRI(_d: number, _p: number): Promise<boolean>;
|
|
92
|
+
getControlLines(_d: number, _p: number): Promise<ControlLine[]>;
|
|
93
|
+
getSupportedControlLines(_d: number, _p: number): Promise<ControlLine[]>;
|
|
94
|
+
setFlowControl(_d: number, _p: number, _flowControl: FlowControl): Promise<void>;
|
|
95
|
+
getFlowControl(_d: number, _p: number): Promise<FlowControl>;
|
|
96
|
+
getSupportedFlowControl(_d: number, _p: number): Promise<FlowControl[]>;
|
|
97
|
+
setBreak(_d: number, _p: number, value: boolean): Promise<void>;
|
|
98
|
+
purgeHwBuffers(_d: number, _p: number, _purgeWrite: boolean, _purgeRead: boolean): Promise<void>;
|
|
99
|
+
getSerial(_d: number, _p: number): Promise<string>;
|
|
100
|
+
onData(listener: Listener<DataEvent>): Subscription;
|
|
101
|
+
onError(listener: Listener<ErrorEvent>): Subscription;
|
|
102
|
+
onConnect(listener: Listener<ConnectEvent>): Subscription;
|
|
103
|
+
onDisconnect(listener: Listener<ConnectEvent>): Subscription;
|
|
104
|
+
/**
|
|
105
|
+
* Permanently close the transport (and the remote port session). Cancels any
|
|
106
|
+
* pending reconnect and stops auto-reconnecting.
|
|
107
|
+
*/
|
|
108
|
+
disconnect(): void;
|
|
109
|
+
}
|
|
110
|
+
export {};
|
|
111
|
+
//# sourceMappingURL=WebSocketSerialTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebSocketSerialTransport.d.ts","sourceRoot":"","sources":["../../../../src/websocket/WebSocketSerialTransport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side core of the WebSocket serial bridge — deliberately free of any
|
|
3
|
+
* `serialport`/`ws`/Node imports so it is unit-testable with fakes. The thin
|
|
4
|
+
* `bin/expose-serial.js` wrapper supplies the real `serialport` port and `ws`
|
|
5
|
+
* socket objects and calls {@link attachBridge} for each connection.
|
|
6
|
+
*/
|
|
7
|
+
import { type PortInfo } from './protocol';
|
|
8
|
+
/** The subset of a `serialport` SerialPort that the bridge uses (callback API). */
|
|
9
|
+
export interface SerialLike {
|
|
10
|
+
write(data: Uint8Array, cb?: (err?: Error | null) => void): void;
|
|
11
|
+
set(opts: {
|
|
12
|
+
dtr?: boolean;
|
|
13
|
+
rts?: boolean;
|
|
14
|
+
brk?: boolean;
|
|
15
|
+
}, cb?: (err?: Error | null) => void): void;
|
|
16
|
+
get(cb: (err: Error | null, signals?: {
|
|
17
|
+
cts?: boolean;
|
|
18
|
+
dsr?: boolean;
|
|
19
|
+
dcd?: boolean;
|
|
20
|
+
ri?: boolean;
|
|
21
|
+
}) => void): void;
|
|
22
|
+
update(opts: {
|
|
23
|
+
baudRate: number;
|
|
24
|
+
}, cb?: (err?: Error | null) => void): void;
|
|
25
|
+
flush(cb?: (err?: Error | null) => void): void;
|
|
26
|
+
drain(cb?: (err?: Error | null) => void): void;
|
|
27
|
+
close(cb?: (err?: Error | null) => void): void;
|
|
28
|
+
on(event: 'data', listener: (data: Uint8Array) => void): void;
|
|
29
|
+
on(event: 'error', listener: (err: Error) => void): void;
|
|
30
|
+
on(event: 'open' | 'close', listener: () => void): void;
|
|
31
|
+
removeListener(event: string, listener: (...args: never[]) => void): void;
|
|
32
|
+
}
|
|
33
|
+
/** The subset of a `ws` WebSocket that the bridge uses. */
|
|
34
|
+
export interface WsLike {
|
|
35
|
+
send(data: string | Uint8Array): void;
|
|
36
|
+
on(event: 'message', listener: (data: unknown, isBinary: boolean) => void): void;
|
|
37
|
+
on(event: 'close', listener: () => void): void;
|
|
38
|
+
on(event: 'error', listener: (err: Error) => void): void;
|
|
39
|
+
}
|
|
40
|
+
export type BridgeOptions = {
|
|
41
|
+
/** Whether the port forwards serial→client data before `startReading`. */
|
|
42
|
+
readingByDefault?: boolean;
|
|
43
|
+
/** Optional logger for diagnostics. */
|
|
44
|
+
log?: (message: string) => void;
|
|
45
|
+
/** Optional static metadata or callback exposed via `getPortInfo`. */
|
|
46
|
+
portInfo?: PortInfo | (() => PortInfo | null | undefined);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Wire a single WebSocket connection to a single serial port: binary frames are
|
|
50
|
+
* piped both ways, JSON control frames invoke the corresponding serial method
|
|
51
|
+
* and get a response, and the port's data/error/close are surfaced as frames.
|
|
52
|
+
* Returns a teardown function that detaches the serial listeners.
|
|
53
|
+
*/
|
|
54
|
+
export declare function attachBridge(serial: SerialLike, ws: WsLike, options?: BridgeOptions): () => void;
|
|
55
|
+
export type BridgeArgs = {
|
|
56
|
+
port?: string;
|
|
57
|
+
baudRate: number;
|
|
58
|
+
wsPort: number;
|
|
59
|
+
host: string;
|
|
60
|
+
allowRemote: boolean;
|
|
61
|
+
help: boolean;
|
|
62
|
+
};
|
|
63
|
+
/** Parse `expose-serial` CLI args + env into a normalised options object. */
|
|
64
|
+
export declare function parseBridgeArgs(argv: readonly string[], env?: Record<string, string | undefined>): BridgeArgs;
|
|
65
|
+
export declare const USAGE = "expose-serial-websocket \u2014 bridge a serial port to a WebSocket\n\nUsage:\n expose-serial-websocket --port <path> [--baudrate 115200] [--ws-port 8080]\n [--host 127.0.0.1] [--allow-remote]\n\nOptions:\n -p, --port <path> Serial device (e.g. /dev/ttyUSB0, COM3) [env SERIAL_PORT]\n -b, --baudrate <n> Baud rate (default 115200) [env BAUD_RATE]\n -w, --ws-port <n> WebSocket port (default 8080) [env WS_PORT]\n --host <addr> Listen address (default 127.0.0.1) [env HOST]\n --allow-remote Bind 0.0.0.0 (exposes the port to the network!)\n -h, --help Show this help\n\nConnect from the app with:\n new Serial(new WebSocketSerialTransport('ws://localhost:8080'))\n";
|
|
66
|
+
//# sourceMappingURL=bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../../../src/websocket/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote-serial-over-WebSocket entry point.
|
|
3
|
+
*
|
|
4
|
+
* import {WebSocketSerialTransport}
|
|
5
|
+
* from 'react-native-web-serial-api/websocket';
|
|
6
|
+
*
|
|
7
|
+
* Client side: `WebSocketSerialTransport` connects an app to a remote serial
|
|
8
|
+
* port. Server side: {@link attachBridge} pipes a WebSocket to a serial port,
|
|
9
|
+
* and {@link SimulatedDeviceToSerialLike} lets that "serial port" be an in-memory
|
|
10
|
+
* {@link SimulatedDevice} simulator (used by `testing/exposeSimulatedDevice`). The
|
|
11
|
+
* wire protocol is in {@link ./protocol}; the bridge core in {@link ./bridge}.
|
|
12
|
+
*/
|
|
13
|
+
export type { BridgeOptions, SerialLike, WsLike } from './bridge';
|
|
14
|
+
export { attachBridge } from './bridge';
|
|
15
|
+
export type { CommandMessage, CommandName, ControlMessage, EventMessage, InputSignals, LineCoding, Parity, PortInfo, ResponseMessage, } from './protocol';
|
|
16
|
+
export { portInfoFromDevice, SimulatedDeviceToSerialLike, } from './serial-device-bridge';
|
|
17
|
+
export type { WebSocketCtor, WebSocketLike, WebSocketSerialOptions, } from './WebSocketSerialTransport';
|
|
18
|
+
export { WebSocketSerialTransport } from './WebSocketSerialTransport';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/websocket/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,YAAY,EAAC,aAAa,EAAE,UAAU,EAAE,MAAM,EAAC,MAAM,UAAU,CAAC;AAChE,OAAO,EAAC,YAAY,EAAC,MAAM,UAAU,CAAC;AACtC,YAAY,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,MAAM,EACN,QAAQ,EACR,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,aAAa,EACb,aAAa,EACb,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAC,wBAAwB,EAAC,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire protocol shared by the WebSocket serial bridge (Node, see
|
|
3
|
+
* {@link ./bridge}) and the client transport ({@link ./WebSocketSerialTransport}).
|
|
4
|
+
*
|
|
5
|
+
* A single WebSocket carries two kinds of frame:
|
|
6
|
+
* - **binary** frames are raw serial bytes (client→bridge = data to write to the
|
|
7
|
+
* port; bridge→client = data read from the port), and
|
|
8
|
+
* - **text** frames are JSON control messages (this module).
|
|
9
|
+
*
|
|
10
|
+
* Control flow is request/response: the client tags each {@link CommandMessage}
|
|
11
|
+
* with an incrementing `id` and the bridge replies with a {@link ResponseMessage}
|
|
12
|
+
* carrying the same `id`. The bridge may also push unsolicited
|
|
13
|
+
* {@link EventMessage}s (port open/close/error).
|
|
14
|
+
*/
|
|
15
|
+
import type { Parity } from '../WebSerial';
|
|
16
|
+
export type { Parity } from '../WebSerial';
|
|
17
|
+
/** Connection parameters for `setLineCoding`. */
|
|
18
|
+
export type LineCoding = {
|
|
19
|
+
baudRate: number;
|
|
20
|
+
dataBits?: number;
|
|
21
|
+
stopBits?: number;
|
|
22
|
+
parity?: Parity;
|
|
23
|
+
};
|
|
24
|
+
/** Input control-signal state returned by `getSignals`. */
|
|
25
|
+
export type InputSignals = {
|
|
26
|
+
cts: boolean;
|
|
27
|
+
dsr: boolean;
|
|
28
|
+
dcd: boolean;
|
|
29
|
+
ri: boolean;
|
|
30
|
+
};
|
|
31
|
+
/** Optional serial-port metadata returned by `getPortInfo`. */
|
|
32
|
+
export type PortInfo = {
|
|
33
|
+
usbVendorId?: number;
|
|
34
|
+
usbProductId?: number;
|
|
35
|
+
serialNumber?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Every control command the bridge understands. */
|
|
38
|
+
export type CommandName = 'setLineCoding' | 'setBaudRate' | 'setSignals' | 'getSignals' | 'getPortInfo' | 'startReading' | 'stopReading' | 'flush' | 'drain' | 'break' | 'close';
|
|
39
|
+
/** client → bridge */
|
|
40
|
+
export type CommandMessage = {
|
|
41
|
+
type: 'command';
|
|
42
|
+
id: number;
|
|
43
|
+
command: CommandName;
|
|
44
|
+
args?: Record<string, unknown>;
|
|
45
|
+
};
|
|
46
|
+
/** bridge → client, answering a {@link CommandMessage} with the same `id`. */
|
|
47
|
+
export type ResponseMessage = {
|
|
48
|
+
type: 'response';
|
|
49
|
+
id: number;
|
|
50
|
+
error: string | null;
|
|
51
|
+
result?: unknown;
|
|
52
|
+
};
|
|
53
|
+
/** An unsolicited port lifecycle event the bridge emits to the client. */
|
|
54
|
+
export type BridgeEventName = 'open' | 'close' | 'error';
|
|
55
|
+
/** bridge → client */
|
|
56
|
+
export type EventMessage = {
|
|
57
|
+
type: 'event';
|
|
58
|
+
event: BridgeEventName;
|
|
59
|
+
error?: string;
|
|
60
|
+
};
|
|
61
|
+
export type ControlMessage = CommandMessage | ResponseMessage | EventMessage;
|
|
62
|
+
/** Parse a text frame into a {@link ControlMessage}, or null if it isn't one. */
|
|
63
|
+
export declare function parseControlMessage(text: string): ControlMessage | null;
|
|
64
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../src/websocket/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEzC,YAAY,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEzC,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;CACb,CAAC;AAEF,+DAA+D;AAC/D,MAAM,MAAM,QAAQ,GAAG;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,oDAAoD;AACpD,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,cAAc,GACd,aAAa,GACb,OAAO,GACP,OAAO,GACP,OAAO,GACP,OAAO,CAAC;AAEZ,sBAAsB;AACtB,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,SAAS,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,CAAC;AAEF,8EAA8E;AAC9E,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,0EAA0E;AAC1E,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAEzD,sBAAsB;AACtB,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,eAAe,GAAG,YAAY,CAAC;AAE7E,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAevE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adapt an in-memory {@link DeviceHandle} simulator to the
|
|
3
|
+
* `serialport`-style {@link SerialLike} that {@link attachBridge} consumes, so a
|
|
4
|
+
* test can expose a *simulated* device over a WebSocket and have a real app
|
|
5
|
+
* connect to it with `new WebSocketSerialTransport(url)`. This is what makes the
|
|
6
|
+
* *same* device-driving test run in Jest (in-memory) and on a device/emulator
|
|
7
|
+
* (over the socket).
|
|
8
|
+
*
|
|
9
|
+
* Pure — no `ws`/`serialport`/Node imports — so it unit-tests with the same
|
|
10
|
+
* `FakeWs` + `attachBridge` fakes the bridge core uses. The lazy-`ws` server
|
|
11
|
+
* wrapper lives in `react-native-web-serial-api/testing` (`exposeSimulatedDevice`).
|
|
12
|
+
*
|
|
13
|
+
* Mapping (host app ⇄ simulator):
|
|
14
|
+
* - client binary frame → `write` → `device.onData`,
|
|
15
|
+
* - `setLineCoding`/`setBaudRate` → `update` → opens the sim + starts reading,
|
|
16
|
+
* - `setSignals` → `set` → `device.onHostSignals`,
|
|
17
|
+
* - `getSignals` → `get` → the device's asserted input signals,
|
|
18
|
+
* - `device.send(...)` → `'data'` → client binary frame,
|
|
19
|
+
* - `getPortInfo` → {@link portInfoFromDevice}.
|
|
20
|
+
*/
|
|
21
|
+
import type { DeviceHandle, InMemorySerialTransport } from '../testing/in-memory-serial-transport';
|
|
22
|
+
import type { SerialLike } from './bridge';
|
|
23
|
+
import type { PortInfo } from './protocol';
|
|
24
|
+
/** The bridge's `getPortInfo` metadata, taken from the device's USB identity. */
|
|
25
|
+
export declare function portInfoFromDevice(device: DeviceHandle): PortInfo;
|
|
26
|
+
/**
|
|
27
|
+
* Build a {@link SerialLike} backed by `device` (already registered on
|
|
28
|
+
* `transport` via `addDevice`). One adapter per WebSocket connection; its
|
|
29
|
+
* transport subscriptions are released when the bridge tears down its listeners.
|
|
30
|
+
*/
|
|
31
|
+
export declare function SimulatedDeviceToSerialLike(transport: InMemorySerialTransport, device: DeviceHandle): SerialLike;
|
|
32
|
+
//# sourceMappingURL=serial-device-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serial-device-bridge.d.ts","sourceRoot":"","sources":["../../../../src/websocket/serial-device-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,uBAAuB,EACxB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AACzC,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAC;AAEzC,iFAAiF;AACjF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAMjE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,uBAAuB,EAClC,MAAM,EAAE,YAAY,GACnB,UAAU,CAiHZ"}
|
package/package.json
CHANGED
|
@@ -1,17 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-web-serial-api",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "W3C Web Serial API (navigator.serial) for React Native on Android, backed by a USB-serial TurboModule (built on mik3y/usb-serial-for-android).",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"react-native": "lib/commonjs/index.js",
|
|
7
7
|
"source": "src/index.ts",
|
|
8
8
|
"types": "lib/typescript/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"source": "./src/index.ts",
|
|
12
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
13
|
+
"react-native": "./lib/commonjs/index.js",
|
|
14
|
+
"default": "./lib/commonjs/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./testing": {
|
|
17
|
+
"source": "./src/testing/index.ts",
|
|
18
|
+
"types": "./lib/typescript/src/testing/index.d.ts",
|
|
19
|
+
"react-native": "./lib/commonjs/testing/index.js",
|
|
20
|
+
"default": "./lib/commonjs/testing/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./websocket": {
|
|
23
|
+
"source": "./src/websocket/index.ts",
|
|
24
|
+
"types": "./lib/typescript/src/websocket/index.d.ts",
|
|
25
|
+
"react-native": "./lib/commonjs/websocket/index.js",
|
|
26
|
+
"default": "./lib/commonjs/websocket/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"bin": {
|
|
31
|
+
"expose-serial-websocket": "bin/expose-serial.js"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"src",
|
|
35
|
+
"lib",
|
|
36
|
+
"android",
|
|
37
|
+
"bin",
|
|
38
|
+
"react-native.config.js",
|
|
39
|
+
"TESTING.md",
|
|
40
|
+
"!android/build",
|
|
41
|
+
"!android/src/test",
|
|
42
|
+
"!**/__tests__",
|
|
43
|
+
"!**/__fixtures__",
|
|
44
|
+
"!**/__mocks__",
|
|
45
|
+
"!**/.*"
|
|
46
|
+
],
|
|
9
47
|
"scripts": {
|
|
10
48
|
"prepare": "bob build",
|
|
11
49
|
"clean": "node -e \"require('fs').rm(\\\"./lib\\\", { recursive: true }, () => {console.log(\\\"'lib' folder deleted\\\")})\"",
|
|
12
50
|
"typecheck": "tsc --noEmit",
|
|
13
|
-
"lint": "biome check
|
|
14
|
-
"format": "biome check --write
|
|
51
|
+
"lint": "biome check",
|
|
52
|
+
"format": "biome check --write",
|
|
53
|
+
"test": "jest",
|
|
54
|
+
"test:watch": "jest --watch",
|
|
55
|
+
"test:coverage": "jest --coverage",
|
|
56
|
+
"test:android": "cd example/android && ./gradlew :react-native-web-serial-api:testDebugUnitTest",
|
|
57
|
+
"test:emulator:e2e": "npm --prefix example run e2e",
|
|
58
|
+
"test:host+emulator": "node ./node_modules/jest/bin/jest.js && npm --prefix example run e2e"
|
|
15
59
|
},
|
|
16
60
|
"keywords": [
|
|
17
61
|
"react-native",
|
|
@@ -46,6 +90,10 @@
|
|
|
46
90
|
"dependencies": {
|
|
47
91
|
"web-streams-polyfill": "^4.3.0"
|
|
48
92
|
},
|
|
93
|
+
"optionalDependencies": {
|
|
94
|
+
"serialport": "^12.0.0",
|
|
95
|
+
"ws": "^8.18.0"
|
|
96
|
+
},
|
|
49
97
|
"peerDependencies": {
|
|
50
98
|
"react": "*",
|
|
51
99
|
"react-native": "*"
|
|
@@ -53,7 +101,13 @@
|
|
|
53
101
|
"devDependencies": {
|
|
54
102
|
"@biomejs/biome": "2.4.16",
|
|
55
103
|
"@react-native/babel-preset": "0.85.3",
|
|
104
|
+
"@react-native/jest-preset": "0.85.3",
|
|
105
|
+
"@types/jest": "^29.5.14",
|
|
106
|
+
"@types/node": "^25.9.2",
|
|
56
107
|
"@types/react": "^19.2.6",
|
|
108
|
+
"@types/ws": "^8.18.1",
|
|
109
|
+
"babel-jest": "29.6.3",
|
|
110
|
+
"jest": "29.6.3",
|
|
57
111
|
"react": "19.2.3",
|
|
58
112
|
"react-native": "0.85.3",
|
|
59
113
|
"react-native-builder-bob": "^0.41.0",
|