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.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -0
  3. package/build/brilliantsole.cjs +5957 -0
  4. package/build/brilliantsole.cjs.map +1 -0
  5. package/build/brilliantsole.js +5448 -0
  6. package/build/brilliantsole.js.map +1 -0
  7. package/build/brilliantsole.ls.js +4872 -0
  8. package/build/brilliantsole.ls.js.map +1 -0
  9. package/build/brilliantsole.min.js +6 -0
  10. package/build/brilliantsole.min.js.map +1 -0
  11. package/build/brilliantsole.module.d.ts +908 -0
  12. package/build/brilliantsole.module.js +5412 -0
  13. package/build/brilliantsole.module.js.map +1 -0
  14. package/build/brilliantsole.module.min.d.ts +908 -0
  15. package/build/brilliantsole.module.min.js +6 -0
  16. package/build/brilliantsole.module.min.js.map +1 -0
  17. package/build/brilliantsole.node.module.d.ts +908 -0
  18. package/build/brilliantsole.node.module.js +5906 -0
  19. package/build/brilliantsole.node.module.js.map +1 -0
  20. package/build/dts/BS.d.ts +25 -0
  21. package/build/dts/Device.d.ts +136 -0
  22. package/build/dts/DeviceInformationManager.d.ts +56 -0
  23. package/build/dts/DeviceManager.d.ts +67 -0
  24. package/build/dts/FileTransferManager.d.ts +84 -0
  25. package/build/dts/FirmwareManager.d.ts +71 -0
  26. package/build/dts/InformationManager.d.ts +66 -0
  27. package/build/dts/TfliteManager.d.ts +92 -0
  28. package/build/dts/connection/BaseConnectionManager.d.ts +59 -0
  29. package/build/dts/connection/ClientConnectionManager.d.ts +23 -0
  30. package/build/dts/connection/WebSocketClientConnectionManager.d.ts +23 -0
  31. package/build/dts/connection/bluetooth/BluetoothConnectionManager.d.ts +10 -0
  32. package/build/dts/connection/bluetooth/NobleConnectionManager.d.ts +42 -0
  33. package/build/dts/connection/bluetooth/WebBluetoothConnectionManager.d.ts +20 -0
  34. package/build/dts/connection/bluetooth/bluetoothUUIDs.d.ts +14 -0
  35. package/build/dts/connection/webSocket/ClientConnectionManager.d.ts +23 -0
  36. package/build/dts/connection/webSocket/WebSocketClientConnectionManager.d.ts +23 -0
  37. package/build/dts/devicePair/DevicePair.d.ts +60 -0
  38. package/build/dts/devicePair/DevicePairPressureSensorDataManager.d.ts +25 -0
  39. package/build/dts/devicePair/DevicePairSensorDataManager.d.ts +33 -0
  40. package/build/dts/scanner/BaseScanner.d.ts +66 -0
  41. package/build/dts/scanner/NobleScanner.d.ts +17 -0
  42. package/build/dts/scanner/Scanner.d.ts +3 -0
  43. package/build/dts/sensor/BarometerSensorDataManager.d.ts +16 -0
  44. package/build/dts/sensor/MotionSensorDataManager.d.ts +69 -0
  45. package/build/dts/sensor/PressureSensorDataManager.d.ts +36 -0
  46. package/build/dts/sensor/SensorConfigurationManager.d.ts +44 -0
  47. package/build/dts/sensor/SensorDataManager.d.ts +40 -0
  48. package/build/dts/server/BaseClient.d.ts +85 -0
  49. package/build/dts/server/BaseServer.d.ts +48 -0
  50. package/build/dts/server/ServerUtils.d.ts +23 -0
  51. package/build/dts/server/udp/UDPServer.d.ts +11 -0
  52. package/build/dts/server/udp/UDPUtils.d.ts +9 -0
  53. package/build/dts/server/websocket/WebSocketClient.d.ts +17 -0
  54. package/build/dts/server/websocket/WebSocketServer.d.ts +13 -0
  55. package/build/dts/server/websocket/WebSocketUtils.d.ts +9 -0
  56. package/build/dts/utils/ArrayBufferUtils.d.ts +7 -0
  57. package/build/dts/utils/ArrayUtils.d.ts +2 -0
  58. package/build/dts/utils/CenterOfPressureHelper.d.ts +15 -0
  59. package/build/dts/utils/Console.d.ts +34 -0
  60. package/build/dts/utils/EventDispatcher.d.ts +50 -0
  61. package/build/dts/utils/EventUtils.d.ts +6 -0
  62. package/build/dts/utils/MathUtils.d.ts +21 -0
  63. package/build/dts/utils/ParseUtils.d.ts +5 -0
  64. package/build/dts/utils/RangeHelper.d.ts +8 -0
  65. package/build/dts/utils/Text.d.ts +6 -0
  66. package/build/dts/utils/Timer.d.ts +14 -0
  67. package/build/dts/utils/TypeScriptUtils.d.ts +19 -0
  68. package/build/dts/utils/cbor.d.ts +6 -0
  69. package/build/dts/utils/checksum.d.ts +3 -0
  70. package/build/dts/utils/environment.d.ts +13 -0
  71. package/build/dts/utils/mcumgr.d.ts +88 -0
  72. package/build/dts/utils/stringUtils.d.ts +2 -0
  73. package/build/dts/vibration/VibrationManager.d.ts +45 -0
  74. package/build/dts/vibration/VibrationWaveformEffects.d.ts +2 -0
  75. package/build/index.d.ts +908 -0
  76. package/build/index.node.d.ts +908 -0
  77. package/examples/3d/index.html +109 -0
  78. package/examples/3d/scene.html +57 -0
  79. package/examples/3d/script.js +419 -0
  80. package/examples/balance/index.html +138 -0
  81. package/examples/balance/script.js +243 -0
  82. package/examples/basic/index.html +327 -0
  83. package/examples/basic/script.js +1093 -0
  84. package/examples/center-of-pressure/index.html +132 -0
  85. package/examples/center-of-pressure/script.js +207 -0
  86. package/examples/device-pair/index.html +72 -0
  87. package/examples/device-pair/script.js +187 -0
  88. package/examples/edge-impulse/index.html +94 -0
  89. package/examples/edge-impulse/script.js +1033 -0
  90. package/examples/graph/index.html +83 -0
  91. package/examples/graph/script.js +469 -0
  92. package/examples/machine-learning/index.html +366 -0
  93. package/examples/machine-learning/script.js +1774 -0
  94. package/examples/pressure/index.html +145 -0
  95. package/examples/pressure/script.js +201 -0
  96. package/examples/recording/index.html +187 -0
  97. package/examples/recording/script.js +736 -0
  98. package/examples/server/index.html +266 -0
  99. package/examples/server/script.js +925 -0
  100. package/examples/utils/aframe/fingertip-button-component.js +201 -0
  101. package/examples/utils/aframe/fingertip-collider-target-component.js +102 -0
  102. package/examples/utils/aframe/fingertip-colliders-component.js +147 -0
  103. package/examples/utils/three/three.module.min.js +24846 -0
  104. package/examples/webxr/index.html +221 -0
  105. package/examples/webxr/script.js +1127 -0
  106. package/package.json +83 -0
  107. package/src/BS.ts +68 -0
  108. package/src/Device.ts +734 -0
  109. package/src/DeviceInformationManager.ts +146 -0
  110. package/src/DeviceManager.ts +354 -0
  111. package/src/FileTransferManager.ts +452 -0
  112. package/src/FirmwareManager.ts +357 -0
  113. package/src/InformationManager.ts +283 -0
  114. package/src/TfliteManager.ts +450 -0
  115. package/src/connection/BaseConnectionManager.ts +255 -0
  116. package/src/connection/ClientConnectionManager.ts +120 -0
  117. package/src/connection/bluetooth/BluetoothConnectionManager.ts +34 -0
  118. package/src/connection/bluetooth/NobleConnectionManager.ts +302 -0
  119. package/src/connection/bluetooth/WebBluetoothConnectionManager.ts +269 -0
  120. package/src/connection/bluetooth/bluetoothUUIDs.ts +218 -0
  121. package/src/devicePair/DevicePair.ts +253 -0
  122. package/src/devicePair/DevicePairPressureSensorDataManager.ts +82 -0
  123. package/src/devicePair/DevicePairSensorDataManager.ts +90 -0
  124. package/src/scanner/BaseScanner.ts +189 -0
  125. package/src/scanner/NobleScanner.ts +195 -0
  126. package/src/scanner/Scanner.ts +16 -0
  127. package/src/sensor/BarometerSensorDataManager.ts +41 -0
  128. package/src/sensor/MotionSensorDataManager.ts +151 -0
  129. package/src/sensor/PressureSensorDataManager.ts +112 -0
  130. package/src/sensor/SensorConfigurationManager.ts +177 -0
  131. package/src/sensor/SensorDataManager.ts +166 -0
  132. package/src/server/BaseClient.ts +368 -0
  133. package/src/server/BaseServer.ts +344 -0
  134. package/src/server/ServerUtils.ts +93 -0
  135. package/src/server/udp/UDPServer.ts +229 -0
  136. package/src/server/udp/UDPUtils.ts +20 -0
  137. package/src/server/websocket/WebSocketClient.ts +179 -0
  138. package/src/server/websocket/WebSocketServer.ts +184 -0
  139. package/src/server/websocket/WebSocketUtils.ts +20 -0
  140. package/src/utils/ArrayBufferUtils.ts +88 -0
  141. package/src/utils/ArrayUtils.ts +15 -0
  142. package/src/utils/CenterOfPressureHelper.ts +39 -0
  143. package/src/utils/Console.ts +156 -0
  144. package/src/utils/EventDispatcher.ts +153 -0
  145. package/src/utils/EventUtils.ts +41 -0
  146. package/src/utils/MathUtils.ts +53 -0
  147. package/src/utils/ParseUtils.ts +46 -0
  148. package/src/utils/RangeHelper.ts +38 -0
  149. package/src/utils/Text.ts +30 -0
  150. package/src/utils/Timer.ts +72 -0
  151. package/src/utils/TypeScriptUtils.ts +22 -0
  152. package/src/utils/cbor.js +429 -0
  153. package/src/utils/checksum.ts +41 -0
  154. package/src/utils/environment.ts +46 -0
  155. package/src/utils/mcumgr.js +444 -0
  156. package/src/utils/stringUtils.ts +11 -0
  157. package/src/vibration/VibrationManager.ts +308 -0
  158. 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;