brilliantsole 0.0.1
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/LICENSE +21 -0
- package/README.md +21 -0
- package/build/brilliantsole.cjs +5957 -0
- package/build/brilliantsole.cjs.map +1 -0
- package/build/brilliantsole.js +5448 -0
- package/build/brilliantsole.js.map +1 -0
- package/build/brilliantsole.ls.js +4872 -0
- package/build/brilliantsole.ls.js.map +1 -0
- package/build/brilliantsole.min.js +6 -0
- package/build/brilliantsole.min.js.map +1 -0
- package/build/brilliantsole.module.d.ts +908 -0
- package/build/brilliantsole.module.js +5412 -0
- package/build/brilliantsole.module.js.map +1 -0
- package/build/brilliantsole.module.min.d.ts +908 -0
- package/build/brilliantsole.module.min.js +6 -0
- package/build/brilliantsole.module.min.js.map +1 -0
- package/build/brilliantsole.node.module.d.ts +908 -0
- package/build/brilliantsole.node.module.js +5906 -0
- package/build/brilliantsole.node.module.js.map +1 -0
- package/build/dts/BS.d.ts +25 -0
- package/build/dts/Device.d.ts +136 -0
- package/build/dts/DeviceInformationManager.d.ts +56 -0
- package/build/dts/DeviceManager.d.ts +67 -0
- package/build/dts/FileTransferManager.d.ts +84 -0
- package/build/dts/FirmwareManager.d.ts +71 -0
- package/build/dts/InformationManager.d.ts +66 -0
- package/build/dts/TfliteManager.d.ts +92 -0
- package/build/dts/connection/BaseConnectionManager.d.ts +59 -0
- package/build/dts/connection/ClientConnectionManager.d.ts +23 -0
- package/build/dts/connection/WebSocketClientConnectionManager.d.ts +23 -0
- package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +10 -0
- package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +42 -0
- package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +20 -0
- package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +14 -0
- package/build/dts/connection/webSocket/ClientConnectionManager.d.ts +23 -0
- package/build/dts/connection/webSocket/WebSocketClientConnectionManager.d.ts +23 -0
- package/build/dts/devicePair/DevicePair.d.ts +60 -0
- package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +25 -0
- package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +33 -0
- package/build/dts/scanner/BaseScanner.d.ts +66 -0
- package/build/dts/scanner/NobleScanner.d.ts +17 -0
- package/build/dts/scanner/Scanner.d.ts +3 -0
- package/build/dts/sensor/BarometerSensorDataManager.d.ts +16 -0
- package/build/dts/sensor/MotionSensorDataManager.d.ts +69 -0
- package/build/dts/sensor/PressureSensorDataManager.d.ts +36 -0
- package/build/dts/sensor/SensorConfigurationManager.d.ts +44 -0
- package/build/dts/sensor/SensorDataManager.d.ts +40 -0
- package/build/dts/server/BaseClient.d.ts +85 -0
- package/build/dts/server/BaseServer.d.ts +48 -0
- package/build/dts/server/ServerUtils.d.ts +23 -0
- package/build/dts/server/udp/UDPServer.d.ts +11 -0
- package/build/dts/server/udp/UDPUtils.d.ts +9 -0
- package/build/dts/server/websocket/WebSocketClient.d.ts +17 -0
- package/build/dts/server/websocket/WebSocketServer.d.ts +13 -0
- package/build/dts/server/websocket/WebSocketUtils.d.ts +9 -0
- package/build/dts/utils/ArrayBufferUtils.d.ts +7 -0
- package/build/dts/utils/ArrayUtils.d.ts +2 -0
- package/build/dts/utils/CenterOfPressureHelper.d.ts +15 -0
- package/build/dts/utils/Console.d.ts +34 -0
- package/build/dts/utils/EventDispatcher.d.ts +50 -0
- package/build/dts/utils/EventUtils.d.ts +6 -0
- package/build/dts/utils/MathUtils.d.ts +21 -0
- package/build/dts/utils/ParseUtils.d.ts +5 -0
- package/build/dts/utils/RangeHelper.d.ts +8 -0
- package/build/dts/utils/Text.d.ts +6 -0
- package/build/dts/utils/Timer.d.ts +14 -0
- package/build/dts/utils/TypeScriptUtils.d.ts +19 -0
- package/build/dts/utils/cbor.d.ts +6 -0
- package/build/dts/utils/checksum.d.ts +3 -0
- package/build/dts/utils/environment.d.ts +13 -0
- package/build/dts/utils/mcumgr.d.ts +88 -0
- package/build/dts/utils/stringUtils.d.ts +2 -0
- package/build/dts/vibration/VibrationManager.d.ts +45 -0
- package/build/dts/vibration/VibrationWaveformEffects.d.ts +2 -0
- package/build/index.d.ts +908 -0
- package/build/index.node.d.ts +908 -0
- package/examples/3d/index.html +109 -0
- package/examples/3d/scene.html +57 -0
- package/examples/3d/script.js +419 -0
- package/examples/balance/index.html +138 -0
- package/examples/balance/script.js +243 -0
- package/examples/basic/index.html +327 -0
- package/examples/basic/script.js +1093 -0
- package/examples/center-of-pressure/index.html +132 -0
- package/examples/center-of-pressure/script.js +207 -0
- package/examples/device-pair/index.html +72 -0
- package/examples/device-pair/script.js +187 -0
- package/examples/edge-impulse/index.html +94 -0
- package/examples/edge-impulse/script.js +1033 -0
- package/examples/graph/index.html +83 -0
- package/examples/graph/script.js +469 -0
- package/examples/machine-learning/index.html +366 -0
- package/examples/machine-learning/script.js +1774 -0
- package/examples/pressure/index.html +145 -0
- package/examples/pressure/script.js +201 -0
- package/examples/recording/index.html +187 -0
- package/examples/recording/script.js +736 -0
- package/examples/server/index.html +266 -0
- package/examples/server/script.js +925 -0
- package/examples/utils/aframe/fingertip-button-component.js +201 -0
- package/examples/utils/aframe/fingertip-collider-target-component.js +102 -0
- package/examples/utils/aframe/fingertip-colliders-component.js +147 -0
- package/examples/utils/three/three.module.min.js +24846 -0
- package/examples/webxr/index.html +221 -0
- package/examples/webxr/script.js +1127 -0
- package/package.json +83 -0
- package/src/BS.ts +68 -0
- package/src/Device.ts +734 -0
- package/src/DeviceInformationManager.ts +146 -0
- package/src/DeviceManager.ts +354 -0
- package/src/FileTransferManager.ts +452 -0
- package/src/FirmwareManager.ts +357 -0
- package/src/InformationManager.ts +283 -0
- package/src/TfliteManager.ts +450 -0
- package/src/connection/BaseConnectionManager.ts +255 -0
- package/src/connection/ClientConnectionManager.ts +120 -0
- package/src/connection/bluetooth/BluetoothConnectionManager.ts +34 -0
- package/src/connection/bluetooth/NobleConnectionManager.ts +302 -0
- package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +269 -0
- package/src/connection/bluetooth/bluetoothUUIDs.ts +218 -0
- package/src/devicePair/DevicePair.ts +253 -0
- package/src/devicePair/DevicePairPressureSensorDataManager.ts +82 -0
- package/src/devicePair/DevicePairSensorDataManager.ts +90 -0
- package/src/scanner/BaseScanner.ts +189 -0
- package/src/scanner/NobleScanner.ts +195 -0
- package/src/scanner/Scanner.ts +16 -0
- package/src/sensor/BarometerSensorDataManager.ts +41 -0
- package/src/sensor/MotionSensorDataManager.ts +151 -0
- package/src/sensor/PressureSensorDataManager.ts +112 -0
- package/src/sensor/SensorConfigurationManager.ts +177 -0
- package/src/sensor/SensorDataManager.ts +166 -0
- package/src/server/BaseClient.ts +368 -0
- package/src/server/BaseServer.ts +344 -0
- package/src/server/ServerUtils.ts +93 -0
- package/src/server/udp/UDPServer.ts +229 -0
- package/src/server/udp/UDPUtils.ts +20 -0
- package/src/server/websocket/WebSocketClient.ts +179 -0
- package/src/server/websocket/WebSocketServer.ts +184 -0
- package/src/server/websocket/WebSocketUtils.ts +20 -0
- package/src/utils/ArrayBufferUtils.ts +88 -0
- package/src/utils/ArrayUtils.ts +15 -0
- package/src/utils/CenterOfPressureHelper.ts +39 -0
- package/src/utils/Console.ts +156 -0
- package/src/utils/EventDispatcher.ts +153 -0
- package/src/utils/EventUtils.ts +41 -0
- package/src/utils/MathUtils.ts +53 -0
- package/src/utils/ParseUtils.ts +46 -0
- package/src/utils/RangeHelper.ts +38 -0
- package/src/utils/Text.ts +30 -0
- package/src/utils/Timer.ts +72 -0
- package/src/utils/TypeScriptUtils.ts +22 -0
- package/src/utils/cbor.js +429 -0
- package/src/utils/checksum.ts +41 -0
- package/src/utils/environment.ts +46 -0
- package/src/utils/mcumgr.js +444 -0
- package/src/utils/stringUtils.ts +11 -0
- package/src/vibration/VibrationManager.ts +308 -0
- package/src/vibration/VibrationWaveformEffects.ts +128 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import Device from "./Device.ts";
|
|
2
|
+
import { createConsole } from "./utils/Console.ts";
|
|
3
|
+
import EventDispatcher from "./utils/EventDispatcher.ts";
|
|
4
|
+
import { textDecoder } from "./utils/Text.ts";
|
|
5
|
+
|
|
6
|
+
const _console = createConsole("DeviceInformationManager", { log: true });
|
|
7
|
+
|
|
8
|
+
export interface PnpId {
|
|
9
|
+
source: "Bluetooth" | "USB";
|
|
10
|
+
vendorId: number;
|
|
11
|
+
productId: number;
|
|
12
|
+
productVersion: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface DeviceInformation {
|
|
16
|
+
manufacturerName: string;
|
|
17
|
+
modelNumber: string;
|
|
18
|
+
softwareRevision: string;
|
|
19
|
+
hardwareRevision: string;
|
|
20
|
+
firmwareRevision: string;
|
|
21
|
+
pnpId: PnpId;
|
|
22
|
+
serialNumber: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const DeviceInformationMessageTypes = [
|
|
26
|
+
"manufacturerName",
|
|
27
|
+
"modelNumber",
|
|
28
|
+
"softwareRevision",
|
|
29
|
+
"hardwareRevision",
|
|
30
|
+
"firmwareRevision",
|
|
31
|
+
"pnpId",
|
|
32
|
+
"serialNumber",
|
|
33
|
+
] as const;
|
|
34
|
+
export type DeviceInformationMessageType = (typeof DeviceInformationMessageTypes)[number];
|
|
35
|
+
|
|
36
|
+
export const DeviceInformationEventTypes = [...DeviceInformationMessageTypes, "deviceInformation"] as const;
|
|
37
|
+
export type DeviceInformationEventType = (typeof DeviceInformationEventTypes)[number];
|
|
38
|
+
|
|
39
|
+
export interface DeviceInformationEventMessages {
|
|
40
|
+
manufacturerName: { manufacturerName: string };
|
|
41
|
+
modelNumber: { modelNumber: string };
|
|
42
|
+
softwareRevision: { softwareRevision: string };
|
|
43
|
+
hardwareRevision: { hardwareRevision: string };
|
|
44
|
+
firmwareRevision: { firmwareRevision: string };
|
|
45
|
+
pnpId: { pnpId: PnpId };
|
|
46
|
+
serialNumber: { serialNumber: string };
|
|
47
|
+
deviceInformation: { deviceInformation: DeviceInformation };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type DeviceInformationEventDispatcher = EventDispatcher<
|
|
51
|
+
Device,
|
|
52
|
+
DeviceInformationEventType,
|
|
53
|
+
DeviceInformationEventMessages
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
class DeviceInformationManager {
|
|
57
|
+
eventDispatcher!: DeviceInformationEventDispatcher;
|
|
58
|
+
get #dispatchEvent() {
|
|
59
|
+
return this.eventDispatcher.dispatchEvent;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
#information: Partial<DeviceInformation> = {};
|
|
63
|
+
get information() {
|
|
64
|
+
return this.#information as DeviceInformation;
|
|
65
|
+
}
|
|
66
|
+
clear() {
|
|
67
|
+
this.#information = {};
|
|
68
|
+
}
|
|
69
|
+
get #isComplete() {
|
|
70
|
+
return DeviceInformationMessageTypes.every((key) => key in this.#information);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
#update(partialDeviceInformation: Partial<DeviceInformation>) {
|
|
74
|
+
_console.log({ partialDeviceInformation });
|
|
75
|
+
const deviceInformationNames = Object.keys(partialDeviceInformation) as (keyof DeviceInformation)[];
|
|
76
|
+
deviceInformationNames.forEach((deviceInformationName) => {
|
|
77
|
+
// @ts-expect-error
|
|
78
|
+
this.#dispatchEvent(deviceInformationName, {
|
|
79
|
+
[deviceInformationName]: partialDeviceInformation[deviceInformationName],
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
Object.assign(this.#information, partialDeviceInformation);
|
|
84
|
+
_console.log({ deviceInformation: this.#information });
|
|
85
|
+
if (this.#isComplete) {
|
|
86
|
+
_console.log("completed deviceInformation");
|
|
87
|
+
this.#dispatchEvent("deviceInformation", { deviceInformation: this.information });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
parseMessage(messageType: DeviceInformationMessageType, dataView: DataView) {
|
|
92
|
+
_console.log({ messageType });
|
|
93
|
+
|
|
94
|
+
switch (messageType) {
|
|
95
|
+
case "manufacturerName":
|
|
96
|
+
const manufacturerName = textDecoder.decode(dataView.buffer);
|
|
97
|
+
_console.log({ manufacturerName });
|
|
98
|
+
this.#update({ manufacturerName });
|
|
99
|
+
break;
|
|
100
|
+
case "modelNumber":
|
|
101
|
+
const modelNumber = textDecoder.decode(dataView.buffer);
|
|
102
|
+
_console.log({ modelNumber });
|
|
103
|
+
this.#update({ modelNumber });
|
|
104
|
+
break;
|
|
105
|
+
case "softwareRevision":
|
|
106
|
+
const softwareRevision = textDecoder.decode(dataView.buffer);
|
|
107
|
+
_console.log({ softwareRevision });
|
|
108
|
+
this.#update({ softwareRevision });
|
|
109
|
+
break;
|
|
110
|
+
case "hardwareRevision":
|
|
111
|
+
const hardwareRevision = textDecoder.decode(dataView.buffer);
|
|
112
|
+
_console.log({ hardwareRevision });
|
|
113
|
+
this.#update({ hardwareRevision });
|
|
114
|
+
break;
|
|
115
|
+
case "firmwareRevision":
|
|
116
|
+
const firmwareRevision = textDecoder.decode(dataView.buffer);
|
|
117
|
+
_console.log({ firmwareRevision });
|
|
118
|
+
this.#update({ firmwareRevision });
|
|
119
|
+
break;
|
|
120
|
+
case "pnpId":
|
|
121
|
+
const pnpId: PnpId = {
|
|
122
|
+
source: dataView.getUint8(0) === 1 ? "Bluetooth" : "USB",
|
|
123
|
+
productId: dataView.getUint16(3, true),
|
|
124
|
+
productVersion: dataView.getUint16(5, true),
|
|
125
|
+
vendorId: 0,
|
|
126
|
+
};
|
|
127
|
+
if (pnpId.source == "Bluetooth") {
|
|
128
|
+
pnpId.vendorId = dataView.getUint16(1, true);
|
|
129
|
+
} else {
|
|
130
|
+
// no need to implement
|
|
131
|
+
}
|
|
132
|
+
_console.log({ pnpId });
|
|
133
|
+
this.#update({ pnpId });
|
|
134
|
+
break;
|
|
135
|
+
case "serialNumber":
|
|
136
|
+
const serialNumber = textDecoder.decode(dataView.buffer);
|
|
137
|
+
_console.log({ serialNumber });
|
|
138
|
+
// will only be used for node
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
throw Error(`uncaught messageType ${messageType}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export default DeviceInformationManager;
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { ConnectionStatus } from "./connection/BaseConnectionManager.ts";
|
|
2
|
+
import WebBluetoothConnectionManager from "./connection/bluetooth/WebBluetoothConnectionManager.ts";
|
|
3
|
+
import Device, { BoundDeviceEventListeners, DeviceEventMap } from "./Device.ts";
|
|
4
|
+
import { DeviceType } from "./InformationManager.ts";
|
|
5
|
+
import { createConsole } from "./utils/Console.ts";
|
|
6
|
+
import { isInBluefy, isInBrowser } from "./utils/environment.ts";
|
|
7
|
+
import EventDispatcher, { BoundEventListeners, Event, EventListenerMap, EventMap } from "./utils/EventDispatcher.ts";
|
|
8
|
+
import { addEventListeners } from "./utils/EventUtils.ts";
|
|
9
|
+
|
|
10
|
+
const _console = createConsole("DeviceManager", { log: true });
|
|
11
|
+
|
|
12
|
+
export interface LocalStorageDeviceInformation {
|
|
13
|
+
type: DeviceType;
|
|
14
|
+
bluetoothId: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface LocalStorageConfiguration {
|
|
18
|
+
devices: LocalStorageDeviceInformation[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const DeviceManagerEventTypes = [
|
|
22
|
+
"deviceConnected",
|
|
23
|
+
"deviceDisconnected",
|
|
24
|
+
"deviceIsConnected",
|
|
25
|
+
"availableDevices",
|
|
26
|
+
"connectedDevices",
|
|
27
|
+
] as const;
|
|
28
|
+
export type DeviceManagerEventType = (typeof DeviceManagerEventTypes)[number];
|
|
29
|
+
|
|
30
|
+
interface DeviceManagerEventMessage {
|
|
31
|
+
device: Device;
|
|
32
|
+
}
|
|
33
|
+
export interface DeviceManagerEventMessages {
|
|
34
|
+
deviceConnected: DeviceManagerEventMessage;
|
|
35
|
+
deviceDisconnected: DeviceManagerEventMessage;
|
|
36
|
+
deviceIsConnected: DeviceManagerEventMessage;
|
|
37
|
+
availableDevices: { availableDevices: Device[] };
|
|
38
|
+
connectedDevices: { connectedDevices: Device[] };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type DeviceManagerEventDispatcher = EventDispatcher<
|
|
42
|
+
DeviceManager,
|
|
43
|
+
DeviceManagerEventType,
|
|
44
|
+
DeviceManagerEventMessages
|
|
45
|
+
>;
|
|
46
|
+
export type DeviceManagerEventMap = EventMap<typeof Device, DeviceManagerEventType, DeviceManagerEventMessages>;
|
|
47
|
+
export type DeviceManagerEventListenerMap = EventListenerMap<
|
|
48
|
+
typeof Device,
|
|
49
|
+
DeviceManagerEventType,
|
|
50
|
+
DeviceManagerEventMessages
|
|
51
|
+
>;
|
|
52
|
+
export type DeviceManagerEvent = Event<typeof Device, DeviceManagerEventType, DeviceManagerEventMessages>;
|
|
53
|
+
export type BoundDeviceManagerEventListeners = BoundEventListeners<
|
|
54
|
+
typeof Device,
|
|
55
|
+
DeviceManagerEventType,
|
|
56
|
+
DeviceManagerEventMessages
|
|
57
|
+
>;
|
|
58
|
+
|
|
59
|
+
class DeviceManager {
|
|
60
|
+
static readonly shared = new DeviceManager();
|
|
61
|
+
|
|
62
|
+
constructor() {
|
|
63
|
+
if (DeviceManager.shared && this != DeviceManager.shared) {
|
|
64
|
+
throw Error("DeviceManager is a singleton - use DeviceManager.shared");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (this.CanUseLocalStorage) {
|
|
68
|
+
this.UseLocalStorage = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// DEVICE LISTENERS
|
|
73
|
+
#boundDeviceEventListeners: BoundDeviceEventListeners = {
|
|
74
|
+
getType: this.#onDeviceType.bind(this),
|
|
75
|
+
isConnected: this.#OnDeviceIsConnected.bind(this),
|
|
76
|
+
};
|
|
77
|
+
/** @private */
|
|
78
|
+
onDevice(device: Device) {
|
|
79
|
+
addEventListeners(device, this.#boundDeviceEventListeners);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#onDeviceType(event: DeviceEventMap["getType"]) {
|
|
83
|
+
if (this.#UseLocalStorage) {
|
|
84
|
+
this.#UpdateLocalStorageConfigurationForDevice(event.target);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// CONNECTION STATUS
|
|
89
|
+
/** @private */
|
|
90
|
+
OnDeviceConnectionStatusUpdated(device: Device, connectionStatus: ConnectionStatus) {
|
|
91
|
+
if (connectionStatus == "notConnected" && !device.canReconnect && this.#AvailableDevices.includes(device)) {
|
|
92
|
+
const deviceIndex = this.#AvailableDevices.indexOf(device);
|
|
93
|
+
this.AvailableDevices.splice(deviceIndex, 1);
|
|
94
|
+
this.#DispatchAvailableDevices();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// CONNECTED DEVICES
|
|
99
|
+
|
|
100
|
+
#ConnectedDevices: Device[] = [];
|
|
101
|
+
get ConnectedDevices() {
|
|
102
|
+
return this.#ConnectedDevices;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#UseLocalStorage = false;
|
|
106
|
+
get UseLocalStorage() {
|
|
107
|
+
return this.#UseLocalStorage;
|
|
108
|
+
}
|
|
109
|
+
set UseLocalStorage(newUseLocalStorage) {
|
|
110
|
+
this.#AssertLocalStorage();
|
|
111
|
+
_console.assertTypeWithError(newUseLocalStorage, "boolean");
|
|
112
|
+
this.#UseLocalStorage = newUseLocalStorage;
|
|
113
|
+
if (this.#UseLocalStorage && !this.#LocalStorageConfiguration) {
|
|
114
|
+
this.#LoadFromLocalStorage();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
#DefaultLocalStorageConfiguration: LocalStorageConfiguration = {
|
|
119
|
+
devices: [],
|
|
120
|
+
};
|
|
121
|
+
#LocalStorageConfiguration?: LocalStorageConfiguration;
|
|
122
|
+
|
|
123
|
+
get CanUseLocalStorage() {
|
|
124
|
+
return isInBrowser && window.localStorage;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#AssertLocalStorage() {
|
|
128
|
+
_console.assertWithError(isInBrowser, "localStorage is only available in the browser");
|
|
129
|
+
_console.assertWithError(window.localStorage, "localStorage not found");
|
|
130
|
+
}
|
|
131
|
+
#LocalStorageKey = "BS.Device";
|
|
132
|
+
#SaveToLocalStorage() {
|
|
133
|
+
this.#AssertLocalStorage();
|
|
134
|
+
localStorage.setItem(this.#LocalStorageKey, JSON.stringify(this.#LocalStorageConfiguration));
|
|
135
|
+
}
|
|
136
|
+
async #LoadFromLocalStorage() {
|
|
137
|
+
this.#AssertLocalStorage();
|
|
138
|
+
let localStorageString = localStorage.getItem(this.#LocalStorageKey);
|
|
139
|
+
if (typeof localStorageString != "string") {
|
|
140
|
+
_console.log("no info found in localStorage");
|
|
141
|
+
this.#LocalStorageConfiguration = Object.assign({}, this.#DefaultLocalStorageConfiguration);
|
|
142
|
+
this.#SaveToLocalStorage();
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const configuration = JSON.parse(localStorageString);
|
|
147
|
+
_console.log({ configuration });
|
|
148
|
+
this.#LocalStorageConfiguration = configuration;
|
|
149
|
+
if (this.CanGetDevices) {
|
|
150
|
+
await this.GetDevices(); // redundant?
|
|
151
|
+
}
|
|
152
|
+
} catch (error) {
|
|
153
|
+
_console.error(error);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
#UpdateLocalStorageConfigurationForDevice(device: Device) {
|
|
158
|
+
if (device.connectionType != "webBluetooth") {
|
|
159
|
+
_console.log("localStorage is only for webBluetooth devices");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
this.#AssertLocalStorage();
|
|
163
|
+
const deviceInformationIndex = this.#LocalStorageConfiguration!.devices.findIndex((deviceInformation) => {
|
|
164
|
+
return deviceInformation.bluetoothId == device.bluetoothId;
|
|
165
|
+
});
|
|
166
|
+
if (deviceInformationIndex == -1) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.#LocalStorageConfiguration!.devices[deviceInformationIndex].type = device.type;
|
|
170
|
+
this.#SaveToLocalStorage();
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// AVAILABLE DEVICES
|
|
174
|
+
#AvailableDevices: Device[] = [];
|
|
175
|
+
get AvailableDevices() {
|
|
176
|
+
return this.#AvailableDevices;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
get CanGetDevices() {
|
|
180
|
+
return isInBrowser && navigator.bluetooth?.getDevices;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* retrieves devices already connected via web bluetooth in other tabs/windows
|
|
184
|
+
*
|
|
185
|
+
* _only available on web-bluetooth enabled browsers_
|
|
186
|
+
*/
|
|
187
|
+
async GetDevices(): Promise<Device[] | undefined> {
|
|
188
|
+
if (!isInBrowser) {
|
|
189
|
+
_console.warn("GetDevices is only available in the browser");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!navigator.bluetooth) {
|
|
194
|
+
_console.warn("bluetooth is not available in this browser");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (isInBluefy) {
|
|
199
|
+
_console.warn("bluefy lists too many devices...");
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!navigator.bluetooth.getDevices) {
|
|
204
|
+
_console.warn("bluetooth.getDevices() is not available in this browser");
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (!this.CanGetDevices) {
|
|
209
|
+
_console.log("CanGetDevices is false");
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!this.#LocalStorageConfiguration) {
|
|
214
|
+
this.#LoadFromLocalStorage();
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const configuration = this.#LocalStorageConfiguration!;
|
|
218
|
+
if (!configuration.devices || configuration.devices.length == 0) {
|
|
219
|
+
_console.log("no devices found in configuration");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const bluetoothDevices = await navigator.bluetooth.getDevices();
|
|
224
|
+
|
|
225
|
+
_console.log({ bluetoothDevices });
|
|
226
|
+
|
|
227
|
+
bluetoothDevices.forEach((bluetoothDevice) => {
|
|
228
|
+
if (!bluetoothDevice.gatt) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
let deviceInformation = configuration.devices.find(
|
|
232
|
+
(deviceInformation) => bluetoothDevice.id == deviceInformation.bluetoothId
|
|
233
|
+
);
|
|
234
|
+
if (!deviceInformation) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
let existingConnectedDevice = this.ConnectedDevices.filter(
|
|
239
|
+
(device) => device.connectionType == "webBluetooth"
|
|
240
|
+
).find((device) => device.bluetoothId == bluetoothDevice.id);
|
|
241
|
+
|
|
242
|
+
const existingAvailableDevice = this.AvailableDevices.filter(
|
|
243
|
+
(device) => device.connectionType == "webBluetooth"
|
|
244
|
+
).find((device) => device.bluetoothId == bluetoothDevice.id);
|
|
245
|
+
if (existingAvailableDevice) {
|
|
246
|
+
if (
|
|
247
|
+
existingConnectedDevice &&
|
|
248
|
+
existingConnectedDevice?.bluetoothId == existingAvailableDevice.bluetoothId &&
|
|
249
|
+
existingConnectedDevice != existingAvailableDevice
|
|
250
|
+
) {
|
|
251
|
+
this.AvailableDevices[this.#AvailableDevices.indexOf(existingAvailableDevice)] = existingConnectedDevice;
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (existingConnectedDevice) {
|
|
257
|
+
this.AvailableDevices.push(existingConnectedDevice);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const device = new Device();
|
|
262
|
+
const connectionManager = new WebBluetoothConnectionManager();
|
|
263
|
+
connectionManager.device = bluetoothDevice;
|
|
264
|
+
if (bluetoothDevice.name) {
|
|
265
|
+
device._informationManager.updateName(bluetoothDevice.name);
|
|
266
|
+
}
|
|
267
|
+
device._informationManager.updateType(deviceInformation.type);
|
|
268
|
+
device.connectionManager = connectionManager;
|
|
269
|
+
this.AvailableDevices.push(device);
|
|
270
|
+
});
|
|
271
|
+
this.#DispatchAvailableDevices();
|
|
272
|
+
return this.AvailableDevices;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// STATIC EVENTLISTENERS
|
|
276
|
+
|
|
277
|
+
#EventDispatcher: DeviceManagerEventDispatcher = new EventDispatcher(this as DeviceManager, DeviceManagerEventTypes);
|
|
278
|
+
|
|
279
|
+
get AddEventListener() {
|
|
280
|
+
return this.#EventDispatcher.addEventListener;
|
|
281
|
+
}
|
|
282
|
+
get #DispatchEvent() {
|
|
283
|
+
return this.#EventDispatcher.dispatchEvent;
|
|
284
|
+
}
|
|
285
|
+
get RemoveEventListener() {
|
|
286
|
+
return this.#EventDispatcher.removeEventListener;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
#OnDeviceIsConnected(event: DeviceEventMap["isConnected"]) {
|
|
290
|
+
const { target: device } = event;
|
|
291
|
+
if (device.isConnected) {
|
|
292
|
+
if (!this.#ConnectedDevices.includes(device)) {
|
|
293
|
+
_console.log("adding device", device);
|
|
294
|
+
this.#ConnectedDevices.push(device);
|
|
295
|
+
if (this.UseLocalStorage && device.connectionType == "webBluetooth") {
|
|
296
|
+
const deviceInformation: LocalStorageDeviceInformation = {
|
|
297
|
+
type: device.type,
|
|
298
|
+
bluetoothId: device.bluetoothId!,
|
|
299
|
+
};
|
|
300
|
+
const deviceInformationIndex = this.#LocalStorageConfiguration!.devices.findIndex(
|
|
301
|
+
(_deviceInformation) => _deviceInformation.bluetoothId == deviceInformation.bluetoothId
|
|
302
|
+
);
|
|
303
|
+
if (deviceInformationIndex == -1) {
|
|
304
|
+
this.#LocalStorageConfiguration!.devices.push(deviceInformation);
|
|
305
|
+
} else {
|
|
306
|
+
this.#LocalStorageConfiguration!.devices[deviceInformationIndex] = deviceInformation;
|
|
307
|
+
}
|
|
308
|
+
this.#SaveToLocalStorage();
|
|
309
|
+
}
|
|
310
|
+
this.#DispatchEvent("deviceConnected", { device });
|
|
311
|
+
this.#DispatchEvent("deviceIsConnected", { device });
|
|
312
|
+
this.#DispatchConnectedDevices();
|
|
313
|
+
} else {
|
|
314
|
+
_console.log("device already included");
|
|
315
|
+
}
|
|
316
|
+
} else {
|
|
317
|
+
if (this.#ConnectedDevices.includes(device)) {
|
|
318
|
+
_console.log("removing device", device);
|
|
319
|
+
this.#ConnectedDevices.splice(this.#ConnectedDevices.indexOf(device), 1);
|
|
320
|
+
this.#DispatchEvent("deviceDisconnected", { device });
|
|
321
|
+
this.#DispatchEvent("deviceIsConnected", { device });
|
|
322
|
+
this.#DispatchConnectedDevices();
|
|
323
|
+
} else {
|
|
324
|
+
_console.log("device already not included");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (this.CanGetDevices) {
|
|
328
|
+
this.GetDevices();
|
|
329
|
+
}
|
|
330
|
+
if (device.isConnected && !this.AvailableDevices.includes(device)) {
|
|
331
|
+
const existingAvailableDevice = this.AvailableDevices.find(
|
|
332
|
+
(_device) => _device.bluetoothId == device.bluetoothId
|
|
333
|
+
);
|
|
334
|
+
_console.log({ existingAvailableDevice });
|
|
335
|
+
if (existingAvailableDevice) {
|
|
336
|
+
this.AvailableDevices[this.AvailableDevices.indexOf(existingAvailableDevice)] = device;
|
|
337
|
+
} else {
|
|
338
|
+
this.AvailableDevices.push(device);
|
|
339
|
+
}
|
|
340
|
+
this.#DispatchAvailableDevices();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
#DispatchAvailableDevices() {
|
|
345
|
+
_console.log({ AvailableDevices: this.AvailableDevices });
|
|
346
|
+
this.#DispatchEvent("availableDevices", { availableDevices: this.AvailableDevices });
|
|
347
|
+
}
|
|
348
|
+
#DispatchConnectedDevices() {
|
|
349
|
+
_console.log({ ConnectedDevices: this.ConnectedDevices });
|
|
350
|
+
this.#DispatchEvent("connectedDevices", { connectedDevices: this.ConnectedDevices });
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export default DeviceManager.shared;
|