@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,36 @@
|
|
|
1
|
+
import { type NativeHardwareBridgeOptions } from './bridge';
|
|
2
|
+
export declare const NATIVE_SECURE_STORAGE_REQUEST_TYPE: "moldable:native-secure-storage";
|
|
3
|
+
export declare const NATIVE_SECURE_STORAGE_RESULT_TYPE: "moldable:native-secure-storage-result";
|
|
4
|
+
export declare const SECURE_STORAGE_MAX_KEY_LENGTH = 128;
|
|
5
|
+
export declare const SECURE_STORAGE_MAX_VALUE_BYTES = 2048;
|
|
6
|
+
export interface MoldableSecureStorageValueResult {
|
|
7
|
+
value: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface MoldableSecureStorageSetResult {
|
|
10
|
+
stored: true;
|
|
11
|
+
}
|
|
12
|
+
export interface MoldableSecureStorageDeleteResult {
|
|
13
|
+
deleted: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface MoldableSecureStorageEntryMetadata {
|
|
16
|
+
key: string;
|
|
17
|
+
createdAtMs: number;
|
|
18
|
+
updatedAtMs: number;
|
|
19
|
+
}
|
|
20
|
+
export interface MoldableSecureStorageListResult {
|
|
21
|
+
entries: MoldableSecureStorageEntryMetadata[];
|
|
22
|
+
}
|
|
23
|
+
export type MoldableSecureStorageBackend = 'keychain' | 'credential-manager' | 'secret-service' | 'unsupported';
|
|
24
|
+
export interface MoldableSecureStorageDiagnostics {
|
|
25
|
+
available: boolean;
|
|
26
|
+
backend: MoldableSecureStorageBackend;
|
|
27
|
+
reason?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Inspect credential-store readiness without reading or returning a secret. */
|
|
30
|
+
export declare function getMoldableSecureStorageDiagnostics(options?: NativeHardwareBridgeOptions): Promise<MoldableSecureStorageDiagnostics>;
|
|
31
|
+
export declare function getMoldableSecureValue(key: string, options?: NativeHardwareBridgeOptions): Promise<MoldableSecureStorageValueResult>;
|
|
32
|
+
export declare function setMoldableSecureValue(key: string, value: string, options?: NativeHardwareBridgeOptions): Promise<MoldableSecureStorageSetResult>;
|
|
33
|
+
export declare function deleteMoldableSecureValue(key: string, options?: NativeHardwareBridgeOptions): Promise<MoldableSecureStorageDeleteResult>;
|
|
34
|
+
/** List entry metadata for the current app and workspace; values are omitted. */
|
|
35
|
+
export declare function listMoldableSecureValues(options?: NativeHardwareBridgeOptions): Promise<MoldableSecureStorageListResult>;
|
|
36
|
+
//# sourceMappingURL=secure-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-storage.d.ts","sourceRoot":"","sources":["../../../src/lib/native-hardware/secure-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,2BAA2B,EAEjC,MAAM,UAAU,CAAA;AAEjB,eAAO,MAAM,kCAAkC,EAC7C,gCAAyC,CAAA;AAC3C,eAAO,MAAM,iCAAiC,EAC5C,uCAAgD,CAAA;AAElD,eAAO,MAAM,6BAA6B,MAAM,CAAA;AAGhD,eAAO,MAAM,8BAA8B,OAAQ,CAAA;AAEnD,MAAM,WAAW,gCAAgC;IAC/C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,IAAI,CAAA;CACb;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,kCAAkC,EAAE,CAAA;CAC9C;AAED,MAAM,MAAM,4BAA4B,GACpC,UAAU,GACV,oBAAoB,GACpB,gBAAgB,GAChB,aAAa,CAAA;AAEjB,MAAM,WAAW,gCAAgC;IAC/C,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,4BAA4B,CAAA;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,gFAAgF;AAChF,wBAAgB,mCAAmC,CACjD,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,gCAAgC,CAAC,CAU3C;AAkBD,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,gCAAgC,CAAC,CAY3C;AAED,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,8BAA8B,CAAC,CAmBzC;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,iCAAiC,CAAC,CAY5C;AAED,iFAAiF;AACjF,wBAAgB,wBAAwB,CACtC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,+BAA+B,CAAC,CAU1C"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { callNativeHardwareBridge, } from './bridge';
|
|
2
|
+
export const NATIVE_SECURE_STORAGE_REQUEST_TYPE = 'moldable:native-secure-storage';
|
|
3
|
+
export const NATIVE_SECURE_STORAGE_RESULT_TYPE = 'moldable:native-secure-storage-result';
|
|
4
|
+
export const SECURE_STORAGE_MAX_KEY_LENGTH = 128;
|
|
5
|
+
// Windows Credential Manager has the smallest commonly supported payload;
|
|
6
|
+
// keeping one cross-platform limit makes behavior portable between hosts.
|
|
7
|
+
export const SECURE_STORAGE_MAX_VALUE_BYTES = 2_048;
|
|
8
|
+
/** Inspect credential-store readiness without reading or returning a secret. */
|
|
9
|
+
export function getMoldableSecureStorageDiagnostics(options = {}) {
|
|
10
|
+
return callNativeHardwareBridge({
|
|
11
|
+
type: NATIVE_SECURE_STORAGE_REQUEST_TYPE,
|
|
12
|
+
capability: 'secure-storage',
|
|
13
|
+
action: 'getDiagnostics',
|
|
14
|
+
}, NATIVE_SECURE_STORAGE_RESULT_TYPE, options);
|
|
15
|
+
}
|
|
16
|
+
function assertValidKey(key) {
|
|
17
|
+
if (key.trim().length === 0 ||
|
|
18
|
+
key.length > SECURE_STORAGE_MAX_KEY_LENGTH ||
|
|
19
|
+
!/^[A-Za-z0-9._-]+$/.test(key)) {
|
|
20
|
+
throw new TypeError(`Secure-storage keys must contain 1-${SECURE_STORAGE_MAX_KEY_LENGTH} ASCII letters, numbers, dots, underscores, or hyphens.`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function utf8Length(value) {
|
|
24
|
+
return new TextEncoder().encode(value).byteLength;
|
|
25
|
+
}
|
|
26
|
+
export function getMoldableSecureValue(key, options = {}) {
|
|
27
|
+
assertValidKey(key);
|
|
28
|
+
return callNativeHardwareBridge({
|
|
29
|
+
type: NATIVE_SECURE_STORAGE_REQUEST_TYPE,
|
|
30
|
+
capability: 'secure-storage',
|
|
31
|
+
action: 'get',
|
|
32
|
+
key,
|
|
33
|
+
}, NATIVE_SECURE_STORAGE_RESULT_TYPE, options);
|
|
34
|
+
}
|
|
35
|
+
export function setMoldableSecureValue(key, value, options = {}) {
|
|
36
|
+
assertValidKey(key);
|
|
37
|
+
if (utf8Length(value) > SECURE_STORAGE_MAX_VALUE_BYTES) {
|
|
38
|
+
throw new TypeError(`Secure-storage values cannot exceed ${SECURE_STORAGE_MAX_VALUE_BYTES} UTF-8 bytes.`);
|
|
39
|
+
}
|
|
40
|
+
return callNativeHardwareBridge({
|
|
41
|
+
type: NATIVE_SECURE_STORAGE_REQUEST_TYPE,
|
|
42
|
+
capability: 'secure-storage',
|
|
43
|
+
action: 'set',
|
|
44
|
+
key,
|
|
45
|
+
value,
|
|
46
|
+
}, NATIVE_SECURE_STORAGE_RESULT_TYPE, options);
|
|
47
|
+
}
|
|
48
|
+
export function deleteMoldableSecureValue(key, options = {}) {
|
|
49
|
+
assertValidKey(key);
|
|
50
|
+
return callNativeHardwareBridge({
|
|
51
|
+
type: NATIVE_SECURE_STORAGE_REQUEST_TYPE,
|
|
52
|
+
capability: 'secure-storage',
|
|
53
|
+
action: 'delete',
|
|
54
|
+
key,
|
|
55
|
+
}, NATIVE_SECURE_STORAGE_RESULT_TYPE, options);
|
|
56
|
+
}
|
|
57
|
+
/** List entry metadata for the current app and workspace; values are omitted. */
|
|
58
|
+
export function listMoldableSecureValues(options = {}) {
|
|
59
|
+
return callNativeHardwareBridge({
|
|
60
|
+
type: NATIVE_SECURE_STORAGE_REQUEST_TYPE,
|
|
61
|
+
capability: 'secure-storage',
|
|
62
|
+
action: 'list',
|
|
63
|
+
}, NATIVE_SECURE_STORAGE_RESULT_TYPE, options);
|
|
64
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type MoldableNativeDeviceDescriptor } from './native-device-io';
|
|
2
|
+
import type { MoldableSerialInputSignals, MoldableSerialOpenOptions, MoldableSerialOutputSignals, MoldableSerialPort, MoldableSerialPortInfo } from './serial';
|
|
3
|
+
export declare class NativeMoldableSerialPort extends EventTarget implements MoldableSerialPort {
|
|
4
|
+
readonly descriptor: MoldableNativeDeviceDescriptor;
|
|
5
|
+
readable: ReadableStream<Uint8Array> | null;
|
|
6
|
+
writable: WritableStream<Uint8Array> | null;
|
|
7
|
+
private handle?;
|
|
8
|
+
private closing?;
|
|
9
|
+
private readonly lifecycle;
|
|
10
|
+
constructor(descriptor: MoldableNativeDeviceDescriptor);
|
|
11
|
+
get connected(): boolean;
|
|
12
|
+
getInfo(): MoldableSerialPortInfo;
|
|
13
|
+
open(options: MoldableSerialOpenOptions): Promise<void>;
|
|
14
|
+
close(): Promise<void>;
|
|
15
|
+
forget(): Promise<void>;
|
|
16
|
+
getSignals(): Promise<MoldableSerialInputSignals>;
|
|
17
|
+
setSignals(signals: MoldableSerialOutputSignals): Promise<void>;
|
|
18
|
+
private createReadable;
|
|
19
|
+
private createWritable;
|
|
20
|
+
private execute;
|
|
21
|
+
}
|
|
22
|
+
export declare function isNativeMoldableSerialPort(port: MoldableSerialPort): port is NativeMoldableSerialPort;
|
|
23
|
+
//# sourceMappingURL=serial-native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serial-native.d.ts","sourceRoot":"","sources":["../../../src/lib/native-hardware/serial-native.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,8BAA8B,EAMpC,MAAM,oBAAoB,CAAA;AAK3B,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,2BAA2B,EAC3B,kBAAkB,EAClB,sBAAsB,EACvB,MAAM,UAAU,CAAA;AAEjB,qBAAa,wBACX,SAAQ,WACR,YAAW,kBAAkB;IAQjB,QAAQ,CAAC,UAAU,EAAE,8BAA8B;IAN/D,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAO;IAClD,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAO;IAClD,OAAO,CAAC,MAAM,CAAC,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAC,CAAe;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;gBAEnC,UAAU,EAAE,8BAA8B;IAI/D,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,IAAI,sBAAsB;IAO3B,IAAI,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCvD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,UAAU,IAAI,OAAO,CAAC,0BAA0B,CAAC;IAsBjD,UAAU,CAAC,OAAO,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;IASrE,OAAO,CAAC,cAAc;IA8BtB,OAAO,CAAC,cAAc;YAqBR,OAAO;CA6BtB;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,kBAAkB,GACvB,IAAI,IAAI,wBAAwB,CAElC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
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
|
+
export class NativeMoldableSerialPort extends EventTarget {
|
|
5
|
+
descriptor;
|
|
6
|
+
readable = null;
|
|
7
|
+
writable = null;
|
|
8
|
+
handle;
|
|
9
|
+
closing;
|
|
10
|
+
lifecycle = new NativeDeviceLifecycle();
|
|
11
|
+
constructor(descriptor) {
|
|
12
|
+
super();
|
|
13
|
+
this.descriptor = descriptor;
|
|
14
|
+
}
|
|
15
|
+
get connected() {
|
|
16
|
+
return this.lifecycle.connected;
|
|
17
|
+
}
|
|
18
|
+
getInfo() {
|
|
19
|
+
return {
|
|
20
|
+
usbVendorId: this.descriptor.vendorId,
|
|
21
|
+
usbProductId: this.descriptor.productId,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
async open(options) {
|
|
25
|
+
if (this.closing)
|
|
26
|
+
await this.closing;
|
|
27
|
+
if (this.handle && this.lifecycle.disconnected)
|
|
28
|
+
await this.close();
|
|
29
|
+
if (this.handle) {
|
|
30
|
+
throw new DOMException('Serial port is already open.', 'InvalidStateError');
|
|
31
|
+
}
|
|
32
|
+
if (options.bufferSize !== undefined) {
|
|
33
|
+
throw new NativeHardwareBridgeError({
|
|
34
|
+
code: 'unsupported',
|
|
35
|
+
message: 'The native serial fallback does not support bufferSize.',
|
|
36
|
+
retryable: false,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const opened = await openMoldableNativeDevice('serial', this.descriptor.selector, {
|
|
40
|
+
baudRate: options.baudRate,
|
|
41
|
+
dataBits: options.dataBits,
|
|
42
|
+
stopBits: options.stopBits,
|
|
43
|
+
parity: options.parity,
|
|
44
|
+
flowControl: options.flowControl,
|
|
45
|
+
});
|
|
46
|
+
if (opened.kind !== 'serial')
|
|
47
|
+
throw new Error('Native device kind mismatch.');
|
|
48
|
+
this.handle = opened.handle;
|
|
49
|
+
this.lifecycle.didOpen();
|
|
50
|
+
this.readable = this.createReadable();
|
|
51
|
+
this.writable = this.createWritable();
|
|
52
|
+
}
|
|
53
|
+
async close() {
|
|
54
|
+
if (this.closing)
|
|
55
|
+
return this.closing;
|
|
56
|
+
if (!this.handle)
|
|
57
|
+
return;
|
|
58
|
+
const handle = this.handle;
|
|
59
|
+
const closing = closeMoldableNativeDevice('serial', handle)
|
|
60
|
+
.then(() => {
|
|
61
|
+
if (this.handle === handle) {
|
|
62
|
+
this.handle = undefined;
|
|
63
|
+
this.readable = null;
|
|
64
|
+
this.writable = null;
|
|
65
|
+
this.lifecycle.didClose();
|
|
66
|
+
}
|
|
67
|
+
})
|
|
68
|
+
.finally(() => {
|
|
69
|
+
if (this.closing === closing)
|
|
70
|
+
this.closing = undefined;
|
|
71
|
+
});
|
|
72
|
+
this.closing = closing;
|
|
73
|
+
return closing;
|
|
74
|
+
}
|
|
75
|
+
async forget() {
|
|
76
|
+
await this.close();
|
|
77
|
+
}
|
|
78
|
+
async getSignals() {
|
|
79
|
+
const result = await this.execute({ action: 'serialGetSignals' });
|
|
80
|
+
if (result.kind !== 'signals' ||
|
|
81
|
+
typeof result.dataCarrierDetect !== 'boolean' ||
|
|
82
|
+
typeof result.clearToSend !== 'boolean' ||
|
|
83
|
+
typeof result.ringIndicator !== 'boolean' ||
|
|
84
|
+
typeof result.dataSetReady !== 'boolean') {
|
|
85
|
+
throw new NativeHardwareBridgeError({
|
|
86
|
+
code: 'invalid_response',
|
|
87
|
+
message: 'Moldable returned invalid serial signals.',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
dataCarrierDetect: result.dataCarrierDetect,
|
|
92
|
+
clearToSend: result.clearToSend,
|
|
93
|
+
ringIndicator: result.ringIndicator,
|
|
94
|
+
dataSetReady: result.dataSetReady,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async setSignals(signals) {
|
|
98
|
+
await this.execute({
|
|
99
|
+
action: 'serialSetSignals',
|
|
100
|
+
dataTerminalReady: signals.dataTerminalReady,
|
|
101
|
+
requestToSend: signals.requestToSend,
|
|
102
|
+
sendBreak: signals.break,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
createReadable() {
|
|
106
|
+
return new ReadableStream({
|
|
107
|
+
pull: async (controller) => {
|
|
108
|
+
if (!this.handle) {
|
|
109
|
+
controller.close();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const result = await this.execute({
|
|
114
|
+
action: 'read',
|
|
115
|
+
endpoint: null,
|
|
116
|
+
length: 65_536,
|
|
117
|
+
timeoutMs: 1_000,
|
|
118
|
+
bulk: false,
|
|
119
|
+
});
|
|
120
|
+
const bytes = bytesFromNativeDeviceResult(result);
|
|
121
|
+
if (bytes.length > 0)
|
|
122
|
+
controller.enqueue(bytes);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
if (error instanceof NativeHardwareBridgeError &&
|
|
126
|
+
error.code === 'timeout') {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
controller.error(error);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
createWritable() {
|
|
135
|
+
return new WritableStream({
|
|
136
|
+
write: async (data) => {
|
|
137
|
+
const result = await this.execute({
|
|
138
|
+
action: 'write',
|
|
139
|
+
endpoint: null,
|
|
140
|
+
data: [...data],
|
|
141
|
+
timeoutMs: 10_000,
|
|
142
|
+
bulk: false,
|
|
143
|
+
});
|
|
144
|
+
if (bytesWrittenFromNativeDeviceResult(result) !== data.byteLength) {
|
|
145
|
+
throw new NativeHardwareBridgeError({
|
|
146
|
+
code: 'host_error',
|
|
147
|
+
message: 'The serial device accepted only part of the write.',
|
|
148
|
+
retryable: true,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
async execute(operation) {
|
|
155
|
+
if (!this.handle) {
|
|
156
|
+
throw new NativeHardwareBridgeError({
|
|
157
|
+
code: 'invalid_request',
|
|
158
|
+
message: 'Serial port is not open.',
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
if (this.lifecycle.disconnected) {
|
|
162
|
+
throw new NativeHardwareBridgeError({
|
|
163
|
+
code: 'unavailable',
|
|
164
|
+
message: 'Serial device is disconnected.',
|
|
165
|
+
retryable: true,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
return await executeMoldableNativeDeviceOperation('serial', this.handle, operation);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
if (isNativeDeviceDisconnect(error)) {
|
|
173
|
+
this.lifecycle.didDisconnect(this, error);
|
|
174
|
+
}
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
export function isNativeMoldableSerialPort(port) {
|
|
180
|
+
return port instanceof NativeMoldableSerialPort;
|
|
181
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface MoldableSerialOperationOptions {
|
|
2
|
+
signal?: AbortSignal;
|
|
3
|
+
}
|
|
4
|
+
export type MoldableBluetoothServiceUuid = number | string;
|
|
5
|
+
export interface MoldableSerialPortFilter {
|
|
6
|
+
usbVendorId?: number;
|
|
7
|
+
usbProductId?: number;
|
|
8
|
+
bluetoothServiceClassId?: MoldableBluetoothServiceUuid;
|
|
9
|
+
}
|
|
10
|
+
export interface MoldableSerialOpenOptions {
|
|
11
|
+
baudRate: number;
|
|
12
|
+
dataBits?: 7 | 8;
|
|
13
|
+
stopBits?: 1 | 2;
|
|
14
|
+
parity?: 'none' | 'even' | 'odd';
|
|
15
|
+
bufferSize?: number;
|
|
16
|
+
flowControl?: 'none' | 'hardware';
|
|
17
|
+
}
|
|
18
|
+
export interface MoldableSerialPortInfo {
|
|
19
|
+
usbVendorId?: number;
|
|
20
|
+
usbProductId?: number;
|
|
21
|
+
bluetoothServiceClassId?: MoldableBluetoothServiceUuid;
|
|
22
|
+
}
|
|
23
|
+
export interface MoldableSerialInputSignals {
|
|
24
|
+
dataCarrierDetect: boolean;
|
|
25
|
+
clearToSend: boolean;
|
|
26
|
+
ringIndicator: boolean;
|
|
27
|
+
dataSetReady: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface MoldableSerialOutputSignals {
|
|
30
|
+
dataTerminalReady?: boolean;
|
|
31
|
+
requestToSend?: boolean;
|
|
32
|
+
break?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** Structural subset of the standard SerialPort interface used by the helpers. */
|
|
35
|
+
export interface MoldableSerialPort extends EventTarget {
|
|
36
|
+
readonly readable: ReadableStream<Uint8Array> | null;
|
|
37
|
+
readonly writable: WritableStream<Uint8Array> | null;
|
|
38
|
+
readonly connected?: boolean;
|
|
39
|
+
getInfo(): MoldableSerialPortInfo;
|
|
40
|
+
open(options: MoldableSerialOpenOptions): Promise<void>;
|
|
41
|
+
close(): Promise<void>;
|
|
42
|
+
forget?(): Promise<void>;
|
|
43
|
+
getSignals(): Promise<MoldableSerialInputSignals>;
|
|
44
|
+
setSignals(signals: MoldableSerialOutputSignals): Promise<void>;
|
|
45
|
+
}
|
|
46
|
+
export interface MoldableSerialRequestOptions extends MoldableSerialOperationOptions {
|
|
47
|
+
filters?: readonly MoldableSerialPortFilter[];
|
|
48
|
+
allowedBluetoothServiceClassIds?: readonly MoldableBluetoothServiceUuid[];
|
|
49
|
+
/** Required when multiple native fallback ports match. Render a user choice. */
|
|
50
|
+
selectNativePort?: (ports: readonly MoldableSerialPort[]) => MoldableSerialPort | Promise<MoldableSerialPort>;
|
|
51
|
+
}
|
|
52
|
+
/** Returns true only when this WebView exposes the Web Serial entry point. */
|
|
53
|
+
export declare function isMoldableSerialSupported(): boolean;
|
|
54
|
+
/** Lists ports previously authorized through Web Serial. */
|
|
55
|
+
export declare function getMoldableSerialPorts(): Promise<MoldableSerialPort[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Shows the browser's serial-port chooser. Call this directly from a user
|
|
58
|
+
* gesture. Aborting stops awaiting the result but may not dismiss the chooser.
|
|
59
|
+
*/
|
|
60
|
+
export declare function requestMoldableSerialPort(options?: MoldableSerialRequestOptions): Promise<MoldableSerialPort>;
|
|
61
|
+
export declare function openMoldableSerialPort(port: MoldableSerialPort, options: MoldableSerialOpenOptions): Promise<void>;
|
|
62
|
+
/** Closes a port after callers have released all stream readers and writers. */
|
|
63
|
+
export declare function closeMoldableSerialPort(port: MoldableSerialPort): Promise<void>;
|
|
64
|
+
/** Revokes the saved permission when the runtime supports SerialPort.forget(). */
|
|
65
|
+
export declare function forgetMoldableSerialPort(port: MoldableSerialPort): Promise<void>;
|
|
66
|
+
export declare function getMoldableSerialSignals(port: MoldableSerialPort): Promise<MoldableSerialInputSignals>;
|
|
67
|
+
export declare function setMoldableSerialSignals(port: MoldableSerialPort, signals: MoldableSerialOutputSignals): Promise<void>;
|
|
68
|
+
/** Reads one available serial chunk and always releases the stream reader. */
|
|
69
|
+
export declare function readMoldableSerialPort(port: MoldableSerialPort, options?: MoldableSerialOperationOptions): Promise<ReadableStreamReadResult<Uint8Array>>;
|
|
70
|
+
/**
|
|
71
|
+
* Writes one serial chunk and releases the stream writer. Aborting rejects the
|
|
72
|
+
* helper promptly and asks the stream to abort; the browser may finish an
|
|
73
|
+
* already-started hardware write before releasing the lock.
|
|
74
|
+
*/
|
|
75
|
+
export declare function writeMoldableSerialPort(port: MoldableSerialPort, data: Uint8Array, options?: MoldableSerialOperationOptions): Promise<void>;
|
|
76
|
+
//# sourceMappingURL=serial.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serial.d.ts","sourceRoot":"","sources":["../../../src/lib/native-hardware/serial.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { NativeHardwareBridgeError } from './bridge';
|
|
2
|
+
import { abortedDeviceIoError, awaitDeviceIoWithAbort, deviceIoError, unsupportedDeviceIoError, } from './device-io-errors';
|
|
3
|
+
import { listMoldableNativeDevices } from './native-device-io';
|
|
4
|
+
import { NativeMoldableSerialPort } from './serial-native';
|
|
5
|
+
function assertNativeSerialFiltersSupported(options) {
|
|
6
|
+
if (options.allowedBluetoothServiceClassIds?.length ||
|
|
7
|
+
options.filters?.some((filter) => filter.bluetoothServiceClassId !== undefined)) {
|
|
8
|
+
throw new NativeHardwareBridgeError({
|
|
9
|
+
code: 'unsupported',
|
|
10
|
+
message: 'The native serial fallback cannot match Bluetooth service identifiers on this platform.',
|
|
11
|
+
retryable: false,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function serialApi() {
|
|
16
|
+
const api = typeof navigator === 'undefined'
|
|
17
|
+
? undefined
|
|
18
|
+
: navigator.serial;
|
|
19
|
+
if (!api)
|
|
20
|
+
throw unsupportedDeviceIoError('serial');
|
|
21
|
+
return api;
|
|
22
|
+
}
|
|
23
|
+
/** Returns true only when this WebView exposes the Web Serial entry point. */
|
|
24
|
+
export function isMoldableSerialSupported() {
|
|
25
|
+
return (typeof navigator !== 'undefined' &&
|
|
26
|
+
!!navigator.serial);
|
|
27
|
+
}
|
|
28
|
+
/** Lists ports previously authorized through Web Serial. */
|
|
29
|
+
export async function getMoldableSerialPorts() {
|
|
30
|
+
if (!isMoldableSerialSupported()) {
|
|
31
|
+
throw unsupportedDeviceIoError('serial');
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
return await serialApi().getPorts();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
throw deviceIoError('serial', 'enumerate', error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Shows the browser's serial-port chooser. Call this directly from a user
|
|
42
|
+
* gesture. Aborting stops awaiting the result but may not dismiss the chooser.
|
|
43
|
+
*/
|
|
44
|
+
export async function requestMoldableSerialPort(options = {}) {
|
|
45
|
+
if (!isMoldableSerialSupported()) {
|
|
46
|
+
assertNativeSerialFiltersSupported(options);
|
|
47
|
+
const descriptors = await listMoldableNativeDevices('serial', {
|
|
48
|
+
signal: options.signal,
|
|
49
|
+
...(options.filters
|
|
50
|
+
? {
|
|
51
|
+
filters: options.filters.map(({ usbVendorId, usbProductId }) => ({
|
|
52
|
+
vendorId: usbVendorId,
|
|
53
|
+
productId: usbProductId,
|
|
54
|
+
})),
|
|
55
|
+
}
|
|
56
|
+
: {}),
|
|
57
|
+
});
|
|
58
|
+
const ports = descriptors
|
|
59
|
+
.filter((descriptor) => !options.filters || options.filters.length === 0
|
|
60
|
+
? true
|
|
61
|
+
: options.filters.some((filter) => (filter.usbVendorId === undefined ||
|
|
62
|
+
filter.usbVendorId === descriptor.vendorId) &&
|
|
63
|
+
(filter.usbProductId === undefined ||
|
|
64
|
+
filter.usbProductId === descriptor.productId)))
|
|
65
|
+
.map((descriptor) => new NativeMoldableSerialPort(descriptor));
|
|
66
|
+
if (ports.length === 0) {
|
|
67
|
+
throw deviceIoError('serial', 'request', new DOMException('No matching serial port is available.', 'NotFoundError'));
|
|
68
|
+
}
|
|
69
|
+
if (ports.length === 1)
|
|
70
|
+
return ports[0];
|
|
71
|
+
if (!options.selectNativePort) {
|
|
72
|
+
throw deviceIoError('serial', 'request', new TypeError('A native port selector is required when multiple serial ports match.'));
|
|
73
|
+
}
|
|
74
|
+
const selected = await options.selectNativePort(ports);
|
|
75
|
+
if (!ports.includes(selected)) {
|
|
76
|
+
throw deviceIoError('serial', 'request', new TypeError('Invalid native serial selection.'));
|
|
77
|
+
}
|
|
78
|
+
return selected;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
return await awaitDeviceIoWithAbort(serialApi().requestPort({
|
|
82
|
+
...(options.filters ? { filters: [...options.filters] } : {}),
|
|
83
|
+
...(options.allowedBluetoothServiceClassIds
|
|
84
|
+
? {
|
|
85
|
+
allowedBluetoothServiceClassIds: [
|
|
86
|
+
...options.allowedBluetoothServiceClassIds,
|
|
87
|
+
],
|
|
88
|
+
}
|
|
89
|
+
: {}),
|
|
90
|
+
}), 'serial', 'request', options.signal);
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw deviceIoError('serial', 'request', error);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export async function openMoldableSerialPort(port, options) {
|
|
97
|
+
try {
|
|
98
|
+
await port.open(options);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw deviceIoError('serial', 'open', error);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/** Closes a port after callers have released all stream readers and writers. */
|
|
105
|
+
export async function closeMoldableSerialPort(port) {
|
|
106
|
+
if (port.readable?.locked || port.writable?.locked) {
|
|
107
|
+
throw deviceIoError('serial', 'close', new DOMException('Release active serial stream readers and writers before closing.', 'InvalidStateError'));
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
await port.close();
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
throw deviceIoError('serial', 'close', error);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/** Revokes the saved permission when the runtime supports SerialPort.forget(). */
|
|
117
|
+
export async function forgetMoldableSerialPort(port) {
|
|
118
|
+
if (typeof port.forget !== 'function') {
|
|
119
|
+
throw unsupportedDeviceIoError('serial');
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
await port.forget();
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
throw deviceIoError('serial', 'close', error);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
export async function getMoldableSerialSignals(port) {
|
|
129
|
+
try {
|
|
130
|
+
return await port.getSignals();
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
throw deviceIoError('serial', 'read', error);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export async function setMoldableSerialSignals(port, signals) {
|
|
137
|
+
try {
|
|
138
|
+
await port.setSignals(signals);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
throw deviceIoError('serial', 'write', error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Reads one available serial chunk and always releases the stream reader. */
|
|
145
|
+
export async function readMoldableSerialPort(port, options = {}) {
|
|
146
|
+
if (options.signal?.aborted) {
|
|
147
|
+
throw abortedDeviceIoError('serial', 'read');
|
|
148
|
+
}
|
|
149
|
+
if (!port.readable) {
|
|
150
|
+
throw deviceIoError('serial', 'read', new DOMException('Serial port is not readable.', 'InvalidStateError'));
|
|
151
|
+
}
|
|
152
|
+
const reader = port.readable.getReader();
|
|
153
|
+
let aborted = false;
|
|
154
|
+
const handleAbort = () => {
|
|
155
|
+
aborted = true;
|
|
156
|
+
void reader.cancel().catch(() => undefined);
|
|
157
|
+
};
|
|
158
|
+
options.signal?.addEventListener('abort', handleAbort, { once: true });
|
|
159
|
+
try {
|
|
160
|
+
const result = await reader.read();
|
|
161
|
+
if (aborted)
|
|
162
|
+
throw abortedDeviceIoError('serial', 'read');
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
throw deviceIoError('serial', 'read', error);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
options.signal?.removeEventListener('abort', handleAbort);
|
|
170
|
+
reader.releaseLock();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Writes one serial chunk and releases the stream writer. Aborting rejects the
|
|
175
|
+
* helper promptly and asks the stream to abort; the browser may finish an
|
|
176
|
+
* already-started hardware write before releasing the lock.
|
|
177
|
+
*/
|
|
178
|
+
export async function writeMoldableSerialPort(port, data, options = {}) {
|
|
179
|
+
if (options.signal?.aborted) {
|
|
180
|
+
throw abortedDeviceIoError('serial', 'write');
|
|
181
|
+
}
|
|
182
|
+
if (!port.writable) {
|
|
183
|
+
throw deviceIoError('serial', 'write', new DOMException('Serial port is not writable.', 'InvalidStateError'));
|
|
184
|
+
}
|
|
185
|
+
const writer = port.writable.getWriter();
|
|
186
|
+
let settled = false;
|
|
187
|
+
let abortPromise;
|
|
188
|
+
const writePromise = writer.write(data).finally(() => {
|
|
189
|
+
settled = true;
|
|
190
|
+
});
|
|
191
|
+
const handleAbort = () => {
|
|
192
|
+
abortPromise = writer.abort(new DOMException('Serial write aborted.', 'AbortError'));
|
|
193
|
+
};
|
|
194
|
+
options.signal?.addEventListener('abort', handleAbort, { once: true });
|
|
195
|
+
try {
|
|
196
|
+
await awaitDeviceIoWithAbort(writePromise, 'serial', 'write', options.signal);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw deviceIoError('serial', 'write', error);
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
options.signal?.removeEventListener('abort', handleAbort);
|
|
203
|
+
if (settled) {
|
|
204
|
+
writer.releaseLock();
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
void Promise.allSettled([writePromise, abortPromise]).then(() => {
|
|
208
|
+
writer.releaseLock();
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|