@moldable-ai/ui 0.2.17 → 0.2.19
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/dist/components/chat/chat-panel.d.ts +18 -12
- package/dist/components/chat/chat-panel.d.ts.map +1 -1
- package/dist/components/chat/chat-panel.js +73 -19
- package/dist/components/chat/index.d.ts +2 -1
- package/dist/components/chat/index.d.ts.map +1 -1
- package/dist/components/chat/index.js +2 -1
- package/dist/components/chat/model-effort-power-effects.d.ts +7 -0
- package/dist/components/chat/model-effort-power-effects.d.ts.map +1 -0
- package/dist/components/chat/model-effort-power-effects.js +54 -0
- package/dist/components/chat/model-effort-selector.d.ts +26 -0
- package/dist/components/chat/model-effort-selector.d.ts.map +1 -0
- package/dist/components/chat/model-effort-selector.js +179 -0
- package/dist/components/chat/model-effort-ultra-effects.d.ts +5 -0
- package/dist/components/chat/model-effort-ultra-effects.d.ts.map +1 -0
- package/dist/components/chat/model-effort-ultra-effects.js +56 -0
- package/dist/components/chat/tool-handlers.d.ts.map +1 -1
- package/dist/components/hardware/bluetooth-panel-helpers.d.ts +9 -0
- package/dist/components/hardware/bluetooth-panel-helpers.d.ts.map +1 -0
- package/dist/components/hardware/bluetooth-panel-helpers.js +37 -0
- package/dist/components/hardware/bluetooth-panel.d.ts +56 -0
- package/dist/components/hardware/bluetooth-panel.d.ts.map +1 -0
- package/dist/components/hardware/bluetooth-panel.js +470 -0
- package/dist/components/hardware/camera-preview.d.ts +39 -0
- package/dist/components/hardware/camera-preview.d.ts.map +1 -0
- package/dist/components/hardware/camera-preview.js +228 -0
- package/dist/components/hardware/capability-badge.d.ts +23 -0
- package/dist/components/hardware/capability-badge.d.ts.map +1 -0
- package/dist/components/hardware/capability-badge.js +39 -0
- package/dist/components/hardware/capability-matrix.d.ts +14 -0
- package/dist/components/hardware/capability-matrix.d.ts.map +1 -0
- package/dist/components/hardware/capability-matrix.js +97 -0
- package/dist/components/hardware/clipboard-button.d.ts +26 -0
- package/dist/components/hardware/clipboard-button.d.ts.map +1 -0
- package/dist/components/hardware/clipboard-button.js +114 -0
- package/dist/components/hardware/device-io-controls.d.ts +4 -0
- package/dist/components/hardware/device-io-controls.d.ts.map +1 -0
- package/dist/components/hardware/device-io-controls.js +28 -0
- package/dist/components/hardware/device-list.d.ts +20 -0
- package/dist/components/hardware/device-list.d.ts.map +1 -0
- package/dist/components/hardware/device-list.js +14 -0
- package/dist/components/hardware/display-map.d.ts +23 -0
- package/dist/components/hardware/display-map.d.ts.map +1 -0
- package/dist/components/hardware/display-map.js +114 -0
- package/dist/components/hardware/haptic-button.d.ts +26 -0
- package/dist/components/hardware/haptic-button.d.ts.map +1 -0
- package/dist/components/hardware/haptic-button.js +94 -0
- package/dist/components/hardware/hardware-panel.d.ts +11 -0
- package/dist/components/hardware/hardware-panel.d.ts.map +1 -0
- package/dist/components/hardware/hardware-panel.js +28 -0
- package/dist/components/hardware/hid-panel.d.ts +40 -0
- package/dist/components/hardware/hid-panel.d.ts.map +1 -0
- package/dist/components/hardware/hid-panel.js +373 -0
- package/dist/components/hardware/index.d.ts +27 -0
- package/dist/components/hardware/index.d.ts.map +1 -0
- package/dist/components/hardware/index.js +26 -0
- package/dist/components/hardware/live-indicator.d.ts +15 -0
- package/dist/components/hardware/live-indicator.d.ts.map +1 -0
- package/dist/components/hardware/live-indicator.js +26 -0
- package/dist/components/hardware/local-auth-button.d.ts +33 -0
- package/dist/components/hardware/local-auth-button.d.ts.map +1 -0
- package/dist/components/hardware/local-auth-button.js +115 -0
- package/dist/components/hardware/location-panel.d.ts +29 -0
- package/dist/components/hardware/location-panel.d.ts.map +1 -0
- package/dist/components/hardware/location-panel.js +154 -0
- package/dist/components/hardware/microphone-meter.d.ts +35 -0
- package/dist/components/hardware/microphone-meter.d.ts.map +1 -0
- package/dist/components/hardware/microphone-meter.js +244 -0
- package/dist/components/hardware/midi-monitor.d.ts +54 -0
- package/dist/components/hardware/midi-monitor.d.ts.map +1 -0
- package/dist/components/hardware/midi-monitor.js +534 -0
- package/dist/components/hardware/notification-panel.d.ts +24 -0
- package/dist/components/hardware/notification-panel.d.ts.map +1 -0
- package/dist/components/hardware/notification-panel.js +124 -0
- package/dist/components/hardware/power-blocker-controller.d.ts +19 -0
- package/dist/components/hardware/power-blocker-controller.d.ts.map +1 -0
- package/dist/components/hardware/power-blocker-controller.js +83 -0
- package/dist/components/hardware/power-panel.d.ts +67 -0
- package/dist/components/hardware/power-panel.d.ts.map +1 -0
- package/dist/components/hardware/power-panel.js +309 -0
- package/dist/components/hardware/readout.d.ts +10 -0
- package/dist/components/hardware/readout.d.ts.map +1 -0
- package/dist/components/hardware/readout.js +11 -0
- package/dist/components/hardware/screen-share-preview.d.ts +36 -0
- package/dist/components/hardware/screen-share-preview.d.ts.map +1 -0
- package/dist/components/hardware/screen-share-preview.js +191 -0
- package/dist/components/hardware/secure-storage-panel.d.ts +36 -0
- package/dist/components/hardware/secure-storage-panel.d.ts.map +1 -0
- package/dist/components/hardware/secure-storage-panel.js +193 -0
- package/dist/components/hardware/serial-console.d.ts +64 -0
- package/dist/components/hardware/serial-console.d.ts.map +1 -0
- package/dist/components/hardware/serial-console.js +399 -0
- package/dist/components/hardware/shortcut-recorder.d.ts +35 -0
- package/dist/components/hardware/shortcut-recorder.d.ts.map +1 -0
- package/dist/components/hardware/shortcut-recorder.js +217 -0
- package/dist/components/hardware/stream-log.d.ts +35 -0
- package/dist/components/hardware/stream-log.d.ts.map +1 -0
- package/dist/components/hardware/stream-log.js +65 -0
- package/dist/components/hardware/system-audio-monitor.d.ts +34 -0
- package/dist/components/hardware/system-audio-monitor.d.ts.map +1 -0
- package/dist/components/hardware/system-audio-monitor.js +275 -0
- package/dist/components/hardware/usb-panel.d.ts +54 -0
- package/dist/components/hardware/usb-panel.d.ts.map +1 -0
- package/dist/components/hardware/usb-panel.js +363 -0
- package/dist/components/hardware/use-capability.d.ts +20 -0
- package/dist/components/hardware/use-capability.d.ts.map +1 -0
- package/dist/components/hardware/use-capability.js +61 -0
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/slider.d.ts +4 -1
- package/dist/components/ui/slider.d.ts.map +1 -1
- package/dist/components/ui/slider.js +2 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/lib/commands.d.ts +59 -0
- package/dist/lib/commands.d.ts.map +1 -1
- package/dist/lib/commands.js +97 -0
- package/dist/lib/native-hardware/bluetooth-access.d.ts +14 -0
- package/dist/lib/native-hardware/bluetooth-access.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-access.js +40 -0
- package/dist/lib/native-hardware/bluetooth-connection.d.ts +19 -0
- package/dist/lib/native-hardware/bluetooth-connection.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-connection.js +88 -0
- package/dist/lib/native-hardware/bluetooth-gatt.d.ts +7 -0
- package/dist/lib/native-hardware/bluetooth-gatt.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-gatt.js +77 -0
- package/dist/lib/native-hardware/bluetooth-internal.d.ts +10 -0
- package/dist/lib/native-hardware/bluetooth-internal.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-internal.js +105 -0
- package/dist/lib/native-hardware/bluetooth-native-fallback.d.ts +33 -0
- package/dist/lib/native-hardware/bluetooth-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-native-fallback.js +214 -0
- package/dist/lib/native-hardware/bluetooth-types.d.ts +85 -0
- package/dist/lib/native-hardware/bluetooth-types.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth-types.js +2 -0
- package/dist/lib/native-hardware/bluetooth.d.ts +7 -0
- package/dist/lib/native-hardware/bluetooth.d.ts.map +1 -0
- package/dist/lib/native-hardware/bluetooth.js +4 -0
- package/dist/lib/native-hardware/bridge.d.ts +23 -0
- package/dist/lib/native-hardware/bridge.d.ts.map +1 -0
- package/dist/lib/native-hardware/bridge.js +266 -0
- package/dist/lib/native-hardware/capabilities.d.ts +7 -0
- package/dist/lib/native-hardware/capabilities.d.ts.map +1 -0
- package/dist/lib/native-hardware/capabilities.js +95 -0
- package/dist/lib/native-hardware/clipboard.d.ts +11 -0
- package/dist/lib/native-hardware/clipboard.d.ts.map +1 -0
- package/dist/lib/native-hardware/clipboard.js +55 -0
- package/dist/lib/native-hardware/device-io-errors.d.ts +11 -0
- package/dist/lib/native-hardware/device-io-errors.d.ts.map +1 -0
- package/dist/lib/native-hardware/device-io-errors.js +82 -0
- package/dist/lib/native-hardware/displays.d.ts +38 -0
- package/dist/lib/native-hardware/displays.d.ts.map +1 -0
- package/dist/lib/native-hardware/displays.js +12 -0
- package/dist/lib/native-hardware/global-shortcuts.d.ts +86 -0
- package/dist/lib/native-hardware/global-shortcuts.d.ts.map +1 -0
- package/dist/lib/native-hardware/global-shortcuts.js +351 -0
- package/dist/lib/native-hardware/haptics.d.ts +25 -0
- package/dist/lib/native-hardware/haptics.d.ts.map +1 -0
- package/dist/lib/native-hardware/haptics.js +18 -0
- package/dist/lib/native-hardware/hid-native.d.ts +26 -0
- package/dist/lib/native-hardware/hid-native.d.ts.map +1 -0
- package/dist/lib/native-hardware/hid-native.js +229 -0
- package/dist/lib/native-hardware/hid.d.ts +52 -0
- package/dist/lib/native-hardware/hid.d.ts.map +1 -0
- package/dist/lib/native-hardware/hid.js +160 -0
- package/dist/lib/native-hardware/index.d.ts +38 -0
- package/dist/lib/native-hardware/index.d.ts.map +1 -0
- package/dist/lib/native-hardware/index.js +20 -0
- package/dist/lib/native-hardware/local-authentication.d.ts +32 -0
- package/dist/lib/native-hardware/local-authentication.d.ts.map +1 -0
- package/dist/lib/native-hardware/local-authentication.js +46 -0
- package/dist/lib/native-hardware/location.d.ts +49 -0
- package/dist/lib/native-hardware/location.d.ts.map +1 -0
- package/dist/lib/native-hardware/location.js +114 -0
- package/dist/lib/native-hardware/media-permissions.d.ts +28 -0
- package/dist/lib/native-hardware/media-permissions.d.ts.map +1 -0
- package/dist/lib/native-hardware/media-permissions.js +37 -0
- package/dist/lib/native-hardware/media.d.ts +17 -0
- package/dist/lib/native-hardware/media.d.ts.map +1 -0
- package/dist/lib/native-hardware/media.js +99 -0
- package/dist/lib/native-hardware/midi-access.d.ts +13 -0
- package/dist/lib/native-hardware/midi-access.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-access.js +66 -0
- package/dist/lib/native-hardware/midi-internal.d.ts +12 -0
- package/dist/lib/native-hardware/midi-internal.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-internal.js +88 -0
- package/dist/lib/native-hardware/midi-native-fallback.d.ts +27 -0
- package/dist/lib/native-hardware/midi-native-fallback.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-native-fallback.js +127 -0
- package/dist/lib/native-hardware/midi-ports.d.ts +6 -0
- package/dist/lib/native-hardware/midi-ports.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-ports.js +115 -0
- package/dist/lib/native-hardware/midi-types.d.ts +25 -0
- package/dist/lib/native-hardware/midi-types.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi-types.js +1 -0
- package/dist/lib/native-hardware/midi.d.ts +6 -0
- package/dist/lib/native-hardware/midi.d.ts.map +1 -0
- package/dist/lib/native-hardware/midi.js +3 -0
- package/dist/lib/native-hardware/native-device-io.d.ts +28 -0
- package/dist/lib/native-hardware/native-device-io.d.ts.map +1 -0
- package/dist/lib/native-hardware/native-device-io.js +91 -0
- package/dist/lib/native-hardware/native-device-lifecycle.d.ts +13 -0
- package/dist/lib/native-hardware/native-device-lifecycle.d.ts.map +1 -0
- package/dist/lib/native-hardware/native-device-lifecycle.js +40 -0
- package/dist/lib/native-hardware/notifications.d.ts +38 -0
- package/dist/lib/native-hardware/notifications.d.ts.map +1 -0
- package/dist/lib/native-hardware/notifications.js +50 -0
- package/dist/lib/native-hardware/power-session.d.ts +113 -0
- package/dist/lib/native-hardware/power-session.d.ts.map +1 -0
- package/dist/lib/native-hardware/power-session.js +264 -0
- package/dist/lib/native-hardware/secure-storage.d.ts +36 -0
- package/dist/lib/native-hardware/secure-storage.d.ts.map +1 -0
- package/dist/lib/native-hardware/secure-storage.js +64 -0
- package/dist/lib/native-hardware/serial-native.d.ts +23 -0
- package/dist/lib/native-hardware/serial-native.d.ts.map +1 -0
- package/dist/lib/native-hardware/serial-native.js +181 -0
- package/dist/lib/native-hardware/serial.d.ts +76 -0
- package/dist/lib/native-hardware/serial.d.ts.map +1 -0
- package/dist/lib/native-hardware/serial.js +212 -0
- package/dist/lib/native-hardware/system-audio.d.ts +127 -0
- package/dist/lib/native-hardware/system-audio.d.ts.map +1 -0
- package/dist/lib/native-hardware/system-audio.js +330 -0
- package/dist/lib/native-hardware/types.d.ts +62 -0
- package/dist/lib/native-hardware/types.d.ts.map +1 -0
- package/dist/lib/native-hardware/types.js +27 -0
- package/dist/lib/native-hardware/usb-native.d.ts +39 -0
- package/dist/lib/native-hardware/usb-native.d.ts.map +1 -0
- package/dist/lib/native-hardware/usb-native.js +217 -0
- package/dist/lib/native-hardware/usb.d.ts +85 -0
- package/dist/lib/native-hardware/usb.d.ts.map +1 -0
- package/dist/lib/native-hardware/usb.js +222 -0
- package/package.json +1 -1
- package/src/styles/index.css +377 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { NativeHardwareBridgeError } from './bridge';
|
|
2
|
+
import { bytesFromNativeDeviceResult, bytesWrittenFromNativeDeviceResult, closeMoldableNativeDevice, executeMoldableNativeDeviceOperation, openMoldableNativeDevice, } from './native-device-io';
|
|
3
|
+
import { NativeDeviceLifecycle, isNativeDeviceDisconnect, } from './native-device-lifecycle';
|
|
4
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
5
|
+
export class NativeMoldableUsbDevice extends EventTarget {
|
|
6
|
+
descriptor;
|
|
7
|
+
vendorId;
|
|
8
|
+
productId;
|
|
9
|
+
productName;
|
|
10
|
+
manufacturerName = null;
|
|
11
|
+
serialNumber = null;
|
|
12
|
+
configuration = null;
|
|
13
|
+
handle;
|
|
14
|
+
closing;
|
|
15
|
+
lifecycle = new NativeDeviceLifecycle();
|
|
16
|
+
constructor(descriptor) {
|
|
17
|
+
super();
|
|
18
|
+
this.descriptor = descriptor;
|
|
19
|
+
this.vendorId = descriptor.vendorId ?? 0;
|
|
20
|
+
this.productId = descriptor.productId ?? 0;
|
|
21
|
+
this.productName = descriptor.label;
|
|
22
|
+
}
|
|
23
|
+
get opened() {
|
|
24
|
+
return this.lifecycle.opened;
|
|
25
|
+
}
|
|
26
|
+
async openWithOptions(options) {
|
|
27
|
+
if (this.closing)
|
|
28
|
+
await this.closing;
|
|
29
|
+
if (this.handle && this.lifecycle.disconnected)
|
|
30
|
+
await this.close();
|
|
31
|
+
if (this.opened)
|
|
32
|
+
return;
|
|
33
|
+
const opened = await openMoldableNativeDevice('usb', this.descriptor.selector, {
|
|
34
|
+
...(options.configurationValue === undefined
|
|
35
|
+
? {}
|
|
36
|
+
: { usbConfiguration: options.configurationValue }),
|
|
37
|
+
usbInterfaces: [...(options.claimInterfaces ?? [])],
|
|
38
|
+
});
|
|
39
|
+
if (opened.kind !== 'usb')
|
|
40
|
+
throw new Error('Native device kind mismatch.');
|
|
41
|
+
this.handle = opened.handle;
|
|
42
|
+
this.lifecycle.didOpen();
|
|
43
|
+
if (options.configurationValue !== undefined) {
|
|
44
|
+
this.configuration = { configurationValue: options.configurationValue };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async open() {
|
|
48
|
+
await this.openWithOptions({});
|
|
49
|
+
}
|
|
50
|
+
async close() {
|
|
51
|
+
if (this.closing)
|
|
52
|
+
return this.closing;
|
|
53
|
+
if (!this.handle)
|
|
54
|
+
return;
|
|
55
|
+
const handle = this.handle;
|
|
56
|
+
const closing = closeMoldableNativeDevice('usb', handle)
|
|
57
|
+
.then(() => {
|
|
58
|
+
if (this.handle === handle) {
|
|
59
|
+
this.handle = undefined;
|
|
60
|
+
this.configuration = null;
|
|
61
|
+
this.lifecycle.didClose();
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
.finally(() => {
|
|
65
|
+
if (this.closing === closing)
|
|
66
|
+
this.closing = undefined;
|
|
67
|
+
});
|
|
68
|
+
this.closing = closing;
|
|
69
|
+
return closing;
|
|
70
|
+
}
|
|
71
|
+
async forget() {
|
|
72
|
+
await this.close();
|
|
73
|
+
}
|
|
74
|
+
async selectConfiguration() {
|
|
75
|
+
throw this.reopenRequired('select a USB configuration');
|
|
76
|
+
}
|
|
77
|
+
async claimInterface() {
|
|
78
|
+
throw this.reopenRequired('claim a USB interface');
|
|
79
|
+
}
|
|
80
|
+
async releaseInterface() {
|
|
81
|
+
throw this.reopenRequired('release a USB interface');
|
|
82
|
+
}
|
|
83
|
+
async transferIn(endpointNumber, length) {
|
|
84
|
+
return this.transferInWithOptions(endpointNumber, length);
|
|
85
|
+
}
|
|
86
|
+
async transferInWithOptions(endpointNumber, length, options = {}) {
|
|
87
|
+
const result = await this.execute({
|
|
88
|
+
action: 'read',
|
|
89
|
+
endpoint: nativeUsbEndpointAddress(endpointNumber, 'in'),
|
|
90
|
+
length,
|
|
91
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
92
|
+
bulk: options.transferType === 'bulk',
|
|
93
|
+
}, options.signal);
|
|
94
|
+
const bytes = bytesFromNativeDeviceResult(result);
|
|
95
|
+
return {
|
|
96
|
+
status: 'ok',
|
|
97
|
+
data: new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async transferOut(endpointNumber, data) {
|
|
101
|
+
return this.transferOutWithOptions(endpointNumber, data);
|
|
102
|
+
}
|
|
103
|
+
async transferOutWithOptions(endpointNumber, data, options = {}) {
|
|
104
|
+
const result = await this.execute({
|
|
105
|
+
action: 'write',
|
|
106
|
+
endpoint: nativeUsbEndpointAddress(endpointNumber, 'out'),
|
|
107
|
+
data: [...asBytes(data)],
|
|
108
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
109
|
+
bulk: options.transferType === 'bulk',
|
|
110
|
+
}, options.signal);
|
|
111
|
+
return {
|
|
112
|
+
status: 'ok',
|
|
113
|
+
bytesWritten: bytesWrittenFromNativeDeviceResult(result),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async controlTransferIn(setup, length) {
|
|
117
|
+
return this.controlTransferInWithOptions(setup, length);
|
|
118
|
+
}
|
|
119
|
+
async controlTransferInWithOptions(setup, length, options = {}) {
|
|
120
|
+
const result = await this.execute({
|
|
121
|
+
action: 'usbControlIn',
|
|
122
|
+
requestType: controlRequestType(setup, true),
|
|
123
|
+
request: setup.request,
|
|
124
|
+
value: setup.value,
|
|
125
|
+
index: setup.index,
|
|
126
|
+
length,
|
|
127
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
128
|
+
}, options.signal);
|
|
129
|
+
const bytes = bytesFromNativeDeviceResult(result);
|
|
130
|
+
return {
|
|
131
|
+
status: 'ok',
|
|
132
|
+
data: new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
async controlTransferOut(setup, data = new Uint8Array()) {
|
|
136
|
+
return this.controlTransferOutWithOptions(setup, data);
|
|
137
|
+
}
|
|
138
|
+
async controlTransferOutWithOptions(setup, data = new Uint8Array(), options = {}) {
|
|
139
|
+
const result = await this.execute({
|
|
140
|
+
action: 'usbControlOut',
|
|
141
|
+
requestType: controlRequestType(setup, false),
|
|
142
|
+
request: setup.request,
|
|
143
|
+
value: setup.value,
|
|
144
|
+
index: setup.index,
|
|
145
|
+
data: [...asBytes(data)],
|
|
146
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
147
|
+
}, options.signal);
|
|
148
|
+
return {
|
|
149
|
+
status: 'ok',
|
|
150
|
+
bytesWritten: bytesWrittenFromNativeDeviceResult(result),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
async clearHalt(direction, endpointNumber) {
|
|
154
|
+
await this.execute({
|
|
155
|
+
action: 'clearUsbHalt',
|
|
156
|
+
endpoint: nativeUsbEndpointAddress(endpointNumber, direction),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async reset() {
|
|
160
|
+
await this.execute({ action: 'resetUsb' });
|
|
161
|
+
}
|
|
162
|
+
async execute(operation, signal) {
|
|
163
|
+
if (!this.handle) {
|
|
164
|
+
throw new NativeHardwareBridgeError({
|
|
165
|
+
code: 'invalid_request',
|
|
166
|
+
message: 'USB device is not open.',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
if (this.lifecycle.disconnected) {
|
|
170
|
+
throw new NativeHardwareBridgeError({
|
|
171
|
+
code: 'unavailable',
|
|
172
|
+
message: 'USB device is disconnected.',
|
|
173
|
+
retryable: true,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
return await executeMoldableNativeDeviceOperation('usb', this.handle, operation, { signal });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
if (isNativeDeviceDisconnect(error)) {
|
|
181
|
+
this.lifecycle.didDisconnect(this, error);
|
|
182
|
+
}
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
reopenRequired(action) {
|
|
187
|
+
return new NativeHardwareBridgeError({
|
|
188
|
+
code: 'invalid_request',
|
|
189
|
+
message: `Close and reopen the native USB device to ${action}.`,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export function isNativeMoldableUsbDevice(device) {
|
|
194
|
+
return device instanceof NativeMoldableUsbDevice;
|
|
195
|
+
}
|
|
196
|
+
function asBytes(data) {
|
|
197
|
+
return data instanceof ArrayBuffer
|
|
198
|
+
? new Uint8Array(data)
|
|
199
|
+
: new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
200
|
+
}
|
|
201
|
+
function nativeUsbEndpointAddress(endpointNumber, direction) {
|
|
202
|
+
if (!Number.isInteger(endpointNumber) ||
|
|
203
|
+
endpointNumber < 1 ||
|
|
204
|
+
endpointNumber > 15) {
|
|
205
|
+
throw new NativeHardwareBridgeError({
|
|
206
|
+
code: 'invalid_request',
|
|
207
|
+
message: 'USB endpointNumber must be an integer between 1 and 15.',
|
|
208
|
+
retryable: false,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return direction === 'in' ? endpointNumber | 0x80 : endpointNumber;
|
|
212
|
+
}
|
|
213
|
+
function controlRequestType(setup, input) {
|
|
214
|
+
const type = { standard: 0, class: 1, vendor: 2 }[setup.requestType] << 5;
|
|
215
|
+
const recipient = { device: 0, interface: 1, endpoint: 2, other: 3 }[setup.recipient];
|
|
216
|
+
return (input ? 0x80 : 0) | type | recipient;
|
|
217
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export interface MoldableUsbOperationOptions {
|
|
2
|
+
signal?: AbortSignal;
|
|
3
|
+
timeoutMs?: number;
|
|
4
|
+
transferType?: 'interrupt' | 'bulk';
|
|
5
|
+
}
|
|
6
|
+
export interface MoldableUsbDeviceFilter {
|
|
7
|
+
vendorId?: number;
|
|
8
|
+
productId?: number;
|
|
9
|
+
classCode?: number;
|
|
10
|
+
subclassCode?: number;
|
|
11
|
+
protocolCode?: number;
|
|
12
|
+
serialNumber?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface MoldableUsbConfiguration {
|
|
15
|
+
configurationValue: number;
|
|
16
|
+
}
|
|
17
|
+
export interface MoldableUsbInTransferResult {
|
|
18
|
+
data?: DataView | null;
|
|
19
|
+
status: 'ok' | 'stall' | 'babble';
|
|
20
|
+
}
|
|
21
|
+
export interface MoldableUsbOutTransferResult {
|
|
22
|
+
bytesWritten?: number;
|
|
23
|
+
status: 'ok' | 'stall' | 'babble';
|
|
24
|
+
}
|
|
25
|
+
export interface MoldableUsbControlTransferParameters {
|
|
26
|
+
requestType: 'standard' | 'class' | 'vendor';
|
|
27
|
+
recipient: 'device' | 'interface' | 'endpoint' | 'other';
|
|
28
|
+
request: number;
|
|
29
|
+
value: number;
|
|
30
|
+
index: number;
|
|
31
|
+
}
|
|
32
|
+
/** Structural subset of the standard USBDevice interface used by the helpers. */
|
|
33
|
+
export interface MoldableUsbDevice extends EventTarget {
|
|
34
|
+
readonly opened: boolean;
|
|
35
|
+
readonly vendorId: number;
|
|
36
|
+
readonly productId: number;
|
|
37
|
+
readonly productName?: string | null;
|
|
38
|
+
readonly manufacturerName?: string | null;
|
|
39
|
+
readonly serialNumber?: string | null;
|
|
40
|
+
readonly configuration?: MoldableUsbConfiguration | null;
|
|
41
|
+
open(): Promise<void>;
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
forget?(): Promise<void>;
|
|
44
|
+
selectConfiguration(configurationValue: number): Promise<void>;
|
|
45
|
+
claimInterface(interfaceNumber: number): Promise<void>;
|
|
46
|
+
releaseInterface(interfaceNumber: number): Promise<void>;
|
|
47
|
+
transferIn(endpointNumber: number, length: number): Promise<MoldableUsbInTransferResult>;
|
|
48
|
+
transferOut(endpointNumber: number, data: BufferSource): Promise<MoldableUsbOutTransferResult>;
|
|
49
|
+
controlTransferIn(setup: MoldableUsbControlTransferParameters, length: number): Promise<MoldableUsbInTransferResult>;
|
|
50
|
+
controlTransferOut(setup: MoldableUsbControlTransferParameters, data?: BufferSource): Promise<MoldableUsbOutTransferResult>;
|
|
51
|
+
clearHalt(direction: 'in' | 'out', endpointNumber: number): Promise<void>;
|
|
52
|
+
reset(): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
export interface MoldableUsbRequestOptions extends MoldableUsbOperationOptions {
|
|
55
|
+
filters: readonly MoldableUsbDeviceFilter[];
|
|
56
|
+
exclusionFilters?: readonly MoldableUsbDeviceFilter[];
|
|
57
|
+
/** Required when multiple native fallback devices match. Render a user choice. */
|
|
58
|
+
selectNativeDevice?: (devices: readonly MoldableUsbDevice[]) => MoldableUsbDevice | Promise<MoldableUsbDevice>;
|
|
59
|
+
}
|
|
60
|
+
export interface MoldableUsbOpenOptions {
|
|
61
|
+
configurationValue?: number;
|
|
62
|
+
claimInterfaces?: readonly number[];
|
|
63
|
+
}
|
|
64
|
+
/** Returns true only when this WebView exposes the WebUSB entry point. */
|
|
65
|
+
export declare function isMoldableUsbSupported(): boolean;
|
|
66
|
+
/** Lists devices previously authorized through WebUSB. */
|
|
67
|
+
export declare function getMoldableUsbDevices(): Promise<MoldableUsbDevice[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Shows the browser's USB chooser. Call this directly from a user gesture.
|
|
70
|
+
* Aborting stops awaiting the result but cannot dismiss every browser chooser.
|
|
71
|
+
*/
|
|
72
|
+
export declare function requestMoldableUsbDevice(options: MoldableUsbRequestOptions): Promise<MoldableUsbDevice>;
|
|
73
|
+
/** Opens, optionally configures, and claims interfaces on a USB device. */
|
|
74
|
+
export declare function openMoldableUsbDevice(device: MoldableUsbDevice, options?: MoldableUsbOpenOptions): Promise<void>;
|
|
75
|
+
/** Releases the selected interfaces and closes an open USB device. */
|
|
76
|
+
export declare function closeMoldableUsbDevice(device: MoldableUsbDevice, releaseInterfaces?: readonly number[]): Promise<void>;
|
|
77
|
+
/** Revokes the saved permission when the runtime supports USBDevice.forget(). */
|
|
78
|
+
export declare function forgetMoldableUsbDevice(device: MoldableUsbDevice): Promise<void>;
|
|
79
|
+
export declare function readMoldableUsbEndpoint(device: MoldableUsbDevice, endpointNumber: number, length: number, options?: MoldableUsbOperationOptions): Promise<MoldableUsbInTransferResult>;
|
|
80
|
+
export declare function writeMoldableUsbEndpoint(device: MoldableUsbDevice, endpointNumber: number, data: BufferSource, options?: MoldableUsbOperationOptions): Promise<MoldableUsbOutTransferResult>;
|
|
81
|
+
export declare function readMoldableUsbControlTransfer(device: MoldableUsbDevice, setup: MoldableUsbControlTransferParameters, length: number, options?: MoldableUsbOperationOptions): Promise<MoldableUsbInTransferResult>;
|
|
82
|
+
export declare function writeMoldableUsbControlTransfer(device: MoldableUsbDevice, setup: MoldableUsbControlTransferParameters, data?: BufferSource, options?: MoldableUsbOperationOptions): Promise<MoldableUsbOutTransferResult>;
|
|
83
|
+
export declare function clearMoldableUsbHalt(device: MoldableUsbDevice, direction: 'in' | 'out', endpointNumber: number): Promise<void>;
|
|
84
|
+
export declare function resetMoldableUsbDevice(device: MoldableUsbDevice): Promise<void>;
|
|
85
|
+
//# sourceMappingURL=usb.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usb.d.ts","sourceRoot":"","sources":["../../../src/lib/native-hardware/usb.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { NativeHardwareBridgeError } from './bridge';
|
|
2
|
+
import { awaitDeviceIoWithAbort, deviceIoError, unsupportedDeviceIoError, } from './device-io-errors';
|
|
3
|
+
import { listMoldableNativeDevices } from './native-device-io';
|
|
4
|
+
import { NativeMoldableUsbDevice, isNativeMoldableUsbDevice, } from './usb-native';
|
|
5
|
+
function assertNativeUsbFiltersSupported(filters) {
|
|
6
|
+
if (filters?.some((filter) => filter.classCode !== undefined ||
|
|
7
|
+
filter.subclassCode !== undefined ||
|
|
8
|
+
filter.protocolCode !== undefined ||
|
|
9
|
+
filter.serialNumber !== undefined)) {
|
|
10
|
+
throw new NativeHardwareBridgeError({
|
|
11
|
+
code: 'unsupported',
|
|
12
|
+
message: 'The native USB fallback can only match vendorId and productId filters on this platform.',
|
|
13
|
+
retryable: false,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function usbApi() {
|
|
18
|
+
const api = typeof navigator === 'undefined'
|
|
19
|
+
? undefined
|
|
20
|
+
: navigator.usb;
|
|
21
|
+
if (!api)
|
|
22
|
+
throw unsupportedDeviceIoError('usb');
|
|
23
|
+
return api;
|
|
24
|
+
}
|
|
25
|
+
/** Returns true only when this WebView exposes the WebUSB entry point. */
|
|
26
|
+
export function isMoldableUsbSupported() {
|
|
27
|
+
return (typeof navigator !== 'undefined' && !!navigator.usb);
|
|
28
|
+
}
|
|
29
|
+
/** Lists devices previously authorized through WebUSB. */
|
|
30
|
+
export async function getMoldableUsbDevices() {
|
|
31
|
+
if (!isMoldableUsbSupported()) {
|
|
32
|
+
throw unsupportedDeviceIoError('usb');
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return await usbApi().getDevices();
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw deviceIoError('usb', 'enumerate', error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Shows the browser's USB chooser. Call this directly from a user gesture.
|
|
43
|
+
* Aborting stops awaiting the result but cannot dismiss every browser chooser.
|
|
44
|
+
*/
|
|
45
|
+
export async function requestMoldableUsbDevice(options) {
|
|
46
|
+
if (!isMoldableUsbSupported()) {
|
|
47
|
+
assertNativeUsbFiltersSupported(options.filters);
|
|
48
|
+
assertNativeUsbFiltersSupported(options.exclusionFilters);
|
|
49
|
+
const descriptors = await listMoldableNativeDevices('usb', {
|
|
50
|
+
signal: options.signal,
|
|
51
|
+
filters: options.filters.map(({ vendorId, productId }) => ({
|
|
52
|
+
vendorId,
|
|
53
|
+
productId,
|
|
54
|
+
})),
|
|
55
|
+
...(options.exclusionFilters
|
|
56
|
+
? {
|
|
57
|
+
exclusionFilters: options.exclusionFilters.map(({ vendorId, productId }) => ({ vendorId, productId })),
|
|
58
|
+
}
|
|
59
|
+
: {}),
|
|
60
|
+
});
|
|
61
|
+
const devices = descriptors
|
|
62
|
+
.filter((descriptor) => options.filters.length === 0
|
|
63
|
+
? true
|
|
64
|
+
: options.filters.some((filter) => (filter.vendorId === undefined ||
|
|
65
|
+
filter.vendorId === descriptor.vendorId) &&
|
|
66
|
+
(filter.productId === undefined ||
|
|
67
|
+
filter.productId === descriptor.productId)))
|
|
68
|
+
.filter((descriptor) => !options.exclusionFilters?.some((filter) => (filter.vendorId === undefined ||
|
|
69
|
+
filter.vendorId === descriptor.vendorId) &&
|
|
70
|
+
(filter.productId === undefined ||
|
|
71
|
+
filter.productId === descriptor.productId)))
|
|
72
|
+
.map((descriptor) => new NativeMoldableUsbDevice(descriptor));
|
|
73
|
+
if (devices.length === 0) {
|
|
74
|
+
throw deviceIoError('usb', 'request', new DOMException('No matching USB device is available.', 'NotFoundError'));
|
|
75
|
+
}
|
|
76
|
+
if (devices.length === 1)
|
|
77
|
+
return devices[0];
|
|
78
|
+
if (!options.selectNativeDevice) {
|
|
79
|
+
throw deviceIoError('usb', 'request', new TypeError('A native device selector is required when multiple USB devices match.'));
|
|
80
|
+
}
|
|
81
|
+
const selected = await options.selectNativeDevice(devices);
|
|
82
|
+
if (!devices.includes(selected)) {
|
|
83
|
+
throw deviceIoError('usb', 'request', new TypeError('Invalid native USB selection.'));
|
|
84
|
+
}
|
|
85
|
+
return selected;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
return await awaitDeviceIoWithAbort(usbApi().requestDevice({
|
|
89
|
+
filters: [...options.filters],
|
|
90
|
+
...(options.exclusionFilters
|
|
91
|
+
? { exclusionFilters: [...options.exclusionFilters] }
|
|
92
|
+
: {}),
|
|
93
|
+
}), 'usb', 'request', options.signal);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw deviceIoError('usb', 'request', error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/** Opens, optionally configures, and claims interfaces on a USB device. */
|
|
100
|
+
export async function openMoldableUsbDevice(device, options = {}) {
|
|
101
|
+
if (isNativeMoldableUsbDevice(device)) {
|
|
102
|
+
await device.openWithOptions(options);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const openedHere = !device.opened;
|
|
106
|
+
const claimed = [];
|
|
107
|
+
try {
|
|
108
|
+
if (openedHere)
|
|
109
|
+
await device.open();
|
|
110
|
+
if (options.configurationValue !== undefined &&
|
|
111
|
+
device.configuration?.configurationValue !== options.configurationValue) {
|
|
112
|
+
await device.selectConfiguration(options.configurationValue);
|
|
113
|
+
}
|
|
114
|
+
for (const interfaceNumber of options.claimInterfaces ?? []) {
|
|
115
|
+
await device.claimInterface(interfaceNumber);
|
|
116
|
+
claimed.push(interfaceNumber);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
await Promise.allSettled(claimed.map((interfaceNumber) => device.releaseInterface(interfaceNumber)));
|
|
121
|
+
if (openedHere)
|
|
122
|
+
await device.close().catch(() => undefined);
|
|
123
|
+
throw deviceIoError('usb', 'open', error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/** Releases the selected interfaces and closes an open USB device. */
|
|
127
|
+
export async function closeMoldableUsbDevice(device, releaseInterfaces = []) {
|
|
128
|
+
if (isNativeMoldableUsbDevice(device)) {
|
|
129
|
+
await device.close();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
let firstError;
|
|
133
|
+
for (const interfaceNumber of releaseInterfaces) {
|
|
134
|
+
try {
|
|
135
|
+
await device.releaseInterface(interfaceNumber);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
firstError ??= error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
if (device.opened)
|
|
143
|
+
await device.close();
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
firstError ??= error;
|
|
147
|
+
}
|
|
148
|
+
if (firstError)
|
|
149
|
+
throw deviceIoError('usb', 'close', firstError);
|
|
150
|
+
}
|
|
151
|
+
/** Revokes the saved permission when the runtime supports USBDevice.forget(). */
|
|
152
|
+
export async function forgetMoldableUsbDevice(device) {
|
|
153
|
+
if (typeof device.forget !== 'function') {
|
|
154
|
+
throw unsupportedDeviceIoError('usb');
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
await device.forget();
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
throw deviceIoError('usb', 'close', error);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
export async function readMoldableUsbEndpoint(device, endpointNumber, length, options = {}) {
|
|
164
|
+
if (isNativeMoldableUsbDevice(device)) {
|
|
165
|
+
return device.transferInWithOptions(endpointNumber, length, options);
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
return await awaitDeviceIoWithAbort(device.transferIn(endpointNumber, length), 'usb', 'read', options.signal);
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
throw deviceIoError('usb', 'read', error);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
export async function writeMoldableUsbEndpoint(device, endpointNumber, data, options = {}) {
|
|
175
|
+
if (isNativeMoldableUsbDevice(device)) {
|
|
176
|
+
return device.transferOutWithOptions(endpointNumber, data, options);
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
return await awaitDeviceIoWithAbort(device.transferOut(endpointNumber, data), 'usb', 'write', options.signal);
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
throw deviceIoError('usb', 'write', error);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export async function readMoldableUsbControlTransfer(device, setup, length, options = {}) {
|
|
186
|
+
if (isNativeMoldableUsbDevice(device)) {
|
|
187
|
+
return device.controlTransferInWithOptions(setup, length, options);
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
return await awaitDeviceIoWithAbort(device.controlTransferIn(setup, length), 'usb', 'read', options.signal);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
throw deviceIoError('usb', 'read', error);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
export async function writeMoldableUsbControlTransfer(device, setup, data, options = {}) {
|
|
197
|
+
if (isNativeMoldableUsbDevice(device)) {
|
|
198
|
+
return device.controlTransferOutWithOptions(setup, data, options);
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
return await awaitDeviceIoWithAbort(device.controlTransferOut(setup, data), 'usb', 'write', options.signal);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
throw deviceIoError('usb', 'write', error);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
export async function clearMoldableUsbHalt(device, direction, endpointNumber) {
|
|
208
|
+
try {
|
|
209
|
+
await device.clearHalt(direction, endpointNumber);
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
throw deviceIoError('usb', 'write', error);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
export async function resetMoldableUsbDevice(device) {
|
|
216
|
+
try {
|
|
217
|
+
await device.reset();
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
throw deviceIoError('usb', 'close', error);
|
|
221
|
+
}
|
|
222
|
+
}
|