@mentra/bluetooth-sdk 0.1.4 → 0.1.6

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 (72) hide show
  1. package/README.md +61 -42
  2. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +20 -12
  3. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +38 -12
  4. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +2 -1
  5. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +45 -51
  6. package/android/src/main/java/com/mentra/bluetoothsdk/audio/AudioModels.kt +125 -0
  7. package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +187 -0
  8. package/android/src/main/java/com/mentra/bluetoothsdk/connection/ConnectionModels.kt +78 -0
  9. package/android/src/main/java/com/mentra/bluetoothsdk/events/BluetoothEvents.kt +60 -0
  10. package/android/src/main/java/com/mentra/bluetoothsdk/internal/MapParsing.kt +132 -0
  11. package/android/src/main/java/com/mentra/bluetoothsdk/requests/DisplayRequests.kt +39 -0
  12. package/android/src/main/java/com/mentra/bluetoothsdk/status/DeviceStatus.kt +605 -0
  13. package/android/src/main/java/com/mentra/bluetoothsdk/status/RuntimeState.kt +199 -0
  14. package/android/src/main/java/com/mentra/bluetoothsdk/status/WifiHotspotStatus.kt +173 -0
  15. package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +348 -0
  16. package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +75 -0
  17. package/build/BluetoothSdk.types.d.ts +24 -7
  18. package/build/BluetoothSdk.types.d.ts.map +1 -1
  19. package/build/BluetoothSdk.types.js.map +1 -1
  20. package/build/_internal.d.ts +1 -1
  21. package/build/_internal.js +1 -1
  22. package/build/_internal.js.map +1 -1
  23. package/build/_private/BluetoothSdkModule.d.ts +5 -4
  24. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  25. package/build/_private/BluetoothSdkModule.js +4 -1
  26. package/build/_private/BluetoothSdkModule.js.map +1 -1
  27. package/build/index.d.ts +4 -3
  28. package/build/index.d.ts.map +1 -1
  29. package/build/index.js +81 -2
  30. package/build/index.js.map +1 -1
  31. package/build/react/index.d.ts +2 -2
  32. package/build/react/index.d.ts.map +1 -1
  33. package/build/react/index.js +1 -2
  34. package/build/react/index.js.map +1 -1
  35. package/build/react/useBluetoothStatus.js +1 -1
  36. package/build/react/useBluetoothStatus.js.map +1 -1
  37. package/build/react/useGlassesConnection.d.ts.map +1 -1
  38. package/build/react/useGlassesConnection.js +13 -0
  39. package/build/react/useGlassesConnection.js.map +1 -1
  40. package/build/react/useMentraBluetooth.d.ts +98 -0
  41. package/build/react/useMentraBluetooth.d.ts.map +1 -0
  42. package/build/react/useMentraBluetooth.js +156 -0
  43. package/build/react/useMentraBluetooth.js.map +1 -0
  44. package/ios/BluetoothSdkModule.swift +9 -9
  45. package/ios/Source/Audio/AudioModels.swift +159 -0
  46. package/ios/Source/Bridge.swift +42 -8
  47. package/ios/Source/Camera/CameraModels.swift +246 -0
  48. package/ios/Source/Connection/ScanSession.swift +27 -0
  49. package/ios/Source/DeviceManager.swift +0 -1
  50. package/ios/Source/DeviceStore.swift +2 -1
  51. package/ios/Source/Errors/BluetoothError.swift +19 -0
  52. package/ios/Source/Events/BluetoothEvents.swift +115 -0
  53. package/ios/Source/Internal/BluetoothAvailability.swift +58 -0
  54. package/ios/Source/Internal/ValueParsing.swift +90 -0
  55. package/ios/Source/MentraBluetoothSDK.swift +32 -2040
  56. package/ios/Source/Requests/DisplayRequests.swift +58 -0
  57. package/ios/Source/Status/DeviceStatus.swift +463 -0
  58. package/ios/Source/Status/RuntimeState.swift +350 -0
  59. package/ios/Source/Status/WifiHotspotStatus.swift +326 -0
  60. package/ios/Source/Streaming/StreamModels.swift +436 -0
  61. package/ios/Source/Types/DeviceModels.swift +134 -0
  62. package/ios/Source/sgcs/G2.swift +97 -36
  63. package/package.json +1 -1
  64. package/src/BluetoothSdk.types.ts +24 -7
  65. package/src/_internal.ts +1 -1
  66. package/src/_private/BluetoothSdkModule.ts +10 -5
  67. package/src/index.ts +93 -4
  68. package/src/react/index.ts +13 -11
  69. package/src/react/useBluetoothStatus.ts +1 -1
  70. package/src/react/useGlassesConnection.ts +15 -0
  71. package/src/react/useMentraBluetooth.ts +307 -0
  72. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +0 -1725
@@ -0,0 +1,307 @@
1
+ import {useState} from "react"
2
+
3
+ import BluetoothSdk from "../index"
4
+ import {
5
+ DeviceModels,
6
+ createDisconnectedGlassesStatus,
7
+ isConnectedGlassesConnectionStatus,
8
+ isReadyGlassesConnectionStatus,
9
+ } from "../BluetoothSdk.types"
10
+ import type {
11
+ ConnectOptions,
12
+ Device,
13
+ DeviceModel,
14
+ GalleryMode,
15
+ GlassesConnectionStatus,
16
+ HotspotStatus,
17
+ PublicBluetoothStatus,
18
+ PublicGlassesStatus,
19
+ MicMode,
20
+ WifiSearchResult,
21
+ WifiStatus,
22
+ } from "../BluetoothSdk.types"
23
+
24
+ import {
25
+ useGlassesConnection,
26
+ type DefaultDeviceStorage,
27
+ type GlassesConnectionHookResult,
28
+ } from "./useGlassesConnection"
29
+
30
+ export type BatteryState = {
31
+ charging: boolean
32
+ level: number | null
33
+ }
34
+
35
+ export type ConnectedGlassesInfo = {
36
+ appVersion?: string
37
+ bluetoothName?: string
38
+ buildNumber?: string
39
+ color?: string
40
+ deviceModel?: string
41
+ firmwareVersion?: string
42
+ serialNumber?: string
43
+ style?: string
44
+ }
45
+
46
+ export type FirmwareInfo = {
47
+ appVersion?: string
48
+ buildNumber?: string
49
+ source:
50
+ | "app"
51
+ | "bes"
52
+ | "device"
53
+ | "firmware"
54
+ | "left"
55
+ | "mtk"
56
+ | "right"
57
+ | "unknown"
58
+ version: string | null
59
+ }
60
+
61
+ export type SignalState = {
62
+ strengthDbm: number | null
63
+ updatedAt: number | null
64
+ }
65
+
66
+ export type GlassesRuntimeState =
67
+ | {
68
+ connected: false
69
+ connection: Exclude<GlassesConnectionStatus, {state: "connected"}>
70
+ ready: false
71
+ }
72
+ | {
73
+ battery: BatteryState
74
+ connected: true
75
+ connection: Extract<GlassesConnectionStatus, {state: "connected"}>
76
+ device: ConnectedGlassesInfo
77
+ firmware: FirmwareInfo
78
+ hotspot: HotspotStatus
79
+ ready: boolean
80
+ signal: SignalState
81
+ wifi: WifiStatus
82
+ }
83
+
84
+ export type GalleryModeState = {
85
+ applying: boolean
86
+ desired: GalleryMode
87
+ error: unknown | null
88
+ }
89
+
90
+ export type PhoneSdkRuntimeState = {
91
+ currentMic: MicMode | null
92
+ defaultDevice: Device | null
93
+ galleryMode: GalleryModeState
94
+ lastLog: string[]
95
+ micRanking: MicMode[]
96
+ otherBluetoothConnected: boolean
97
+ searching: boolean
98
+ searchingController: boolean
99
+ systemMicUnavailable: boolean
100
+ wifiScanResults: WifiSearchResult[]
101
+ }
102
+
103
+ export type ScanController = {
104
+ active: boolean
105
+ clear: () => void
106
+ devices: Device[]
107
+ error: unknown | null
108
+ model: DeviceModel
109
+ selectedDevice: Device | null
110
+ selectDevice: (device: Device | null) => void
111
+ setModel: (model: DeviceModel) => void
112
+ start: (model?: DeviceModel) => Promise<Device[]>
113
+ stop: () => Promise<void>
114
+ }
115
+
116
+ export type UseMentraBluetoothOptions = {
117
+ autoConnectDefault?: boolean
118
+ defaultDeviceStorage?: DefaultDeviceStorage
119
+ defaultModel?: DeviceModel
120
+ onError?: (error: unknown) => void
121
+ scanTimeoutMs?: number
122
+ }
123
+
124
+ export type MentraBluetoothSession = {
125
+ busy: boolean
126
+ clearDefaultDevice: () => Promise<void>
127
+ connect: (device?: Device, options?: ConnectOptions) => Promise<void>
128
+ connectDefault: (options?: ConnectOptions) => Promise<void>
129
+ defaultDevice: Device | null
130
+ disconnect: () => Promise<void>
131
+ error: unknown | null
132
+ glasses: GlassesRuntimeState
133
+ refresh: () => Promise<void>
134
+ scan: ScanController
135
+ sdk: PhoneSdkRuntimeState
136
+ setDefaultDevice: (device: Device | null) => Promise<void>
137
+ setGalleryMode: (mode: GalleryMode) => Promise<void>
138
+ }
139
+
140
+ function stringValue(value: unknown): string | undefined {
141
+ return typeof value === "string" && value.length > 0 ? value : undefined
142
+ }
143
+
144
+ function numberValue(value: unknown): number | null {
145
+ return typeof value === "number" && Number.isFinite(value) ? value : null
146
+ }
147
+
148
+ function firmwareInfo(status: Partial<PublicGlassesStatus>): FirmwareInfo {
149
+ const firmwareSources = [
150
+ ["firmwareVersion", "firmware"],
151
+ ["deviceFirmwareVersion", "device"],
152
+ ["rightFirmwareVersion", "right"],
153
+ ["leftFirmwareVersion", "left"],
154
+ ["besFirmwareVersion", "bes"],
155
+ ["mtkFirmwareVersion", "mtk"],
156
+ ["appVersion", "app"],
157
+ ] as const
158
+
159
+ for (const [key, source] of firmwareSources) {
160
+ const value = stringValue((status as Record<string, unknown>)[key])
161
+ if (value) {
162
+ return {
163
+ appVersion: stringValue(status.appVersion),
164
+ buildNumber: stringValue(status.buildNumber),
165
+ source,
166
+ version: value,
167
+ }
168
+ }
169
+ }
170
+
171
+ return {
172
+ appVersion: stringValue(status.appVersion),
173
+ buildNumber: stringValue(status.buildNumber),
174
+ source: "unknown",
175
+ version: null,
176
+ }
177
+ }
178
+
179
+ function batteryState(status: Partial<PublicGlassesStatus>): BatteryState {
180
+ const level = typeof status.batteryLevel === "number" && status.batteryLevel >= 0 ? status.batteryLevel : null
181
+ return {
182
+ charging: status.charging ?? false,
183
+ level,
184
+ }
185
+ }
186
+
187
+ function connectedGlassesInfo(status: Partial<PublicGlassesStatus>): ConnectedGlassesInfo {
188
+ return {
189
+ appVersion: stringValue(status.appVersion),
190
+ bluetoothName: stringValue(status.bluetoothName),
191
+ buildNumber: stringValue(status.buildNumber),
192
+ color: stringValue(status.color),
193
+ deviceModel: stringValue(status.deviceModel),
194
+ firmwareVersion: stringValue(status.firmwareVersion),
195
+ serialNumber: stringValue(status.serialNumber),
196
+ style: stringValue(status.style),
197
+ }
198
+ }
199
+
200
+ function runtimeGlassesState(status: Partial<PublicGlassesStatus>): GlassesRuntimeState {
201
+ const connection = status.connection ?? createDisconnectedGlassesStatus().connection ?? {state: "disconnected"}
202
+
203
+ if (!isConnectedGlassesConnectionStatus(connection)) {
204
+ return {
205
+ connected: false,
206
+ connection,
207
+ ready: false,
208
+ }
209
+ }
210
+
211
+ return {
212
+ battery: batteryState(status),
213
+ connected: true,
214
+ connection,
215
+ device: connectedGlassesInfo(status),
216
+ firmware: firmwareInfo(status),
217
+ hotspot: status.hotspot ?? {state: "disabled"},
218
+ ready: isReadyGlassesConnectionStatus(connection),
219
+ signal: {
220
+ strengthDbm: numberValue((status as Record<string, unknown>).signalStrength),
221
+ updatedAt: numberValue((status as Record<string, unknown>).signalStrengthUpdatedAt),
222
+ },
223
+ wifi: status.wifi ?? {state: "disconnected"},
224
+ }
225
+ }
226
+
227
+ function phoneSdkState(
228
+ status: Partial<PublicBluetoothStatus>,
229
+ defaultDevice: Device | null,
230
+ galleryMode: GalleryModeState,
231
+ ): PhoneSdkRuntimeState {
232
+ return {
233
+ currentMic: status.currentMic || null,
234
+ defaultDevice,
235
+ galleryMode,
236
+ lastLog: status.lastLog ?? [],
237
+ micRanking: status.micRanking ?? [],
238
+ otherBluetoothConnected: status.otherBtConnected ?? false,
239
+ searching: status.searching ?? false,
240
+ searchingController: status.searchingController ?? false,
241
+ systemMicUnavailable: status.systemMicUnavailable ?? false,
242
+ wifiScanResults: status.wifiScanResults ?? [],
243
+ }
244
+ }
245
+
246
+ function scanController(connection: GlassesConnectionHookResult): ScanController {
247
+ return {
248
+ active: connection.scan.scanning,
249
+ clear: connection.scan.clearResults,
250
+ devices: connection.scan.devices,
251
+ error: connection.scan.error,
252
+ model: connection.scan.model,
253
+ selectedDevice: connection.scan.selectedDevice,
254
+ selectDevice: connection.scan.selectDevice,
255
+ setModel: connection.scan.setModel,
256
+ start: connection.scan.startScan,
257
+ stop: connection.scan.stopScan,
258
+ }
259
+ }
260
+
261
+ export function useMentraBluetooth(options: UseMentraBluetoothOptions = {}): MentraBluetoothSession {
262
+ const connection = useGlassesConnection({
263
+ autoConnectDefault: options.autoConnectDefault,
264
+ defaultDeviceStorage: options.defaultDeviceStorage,
265
+ onError: options.onError,
266
+ scanModel: options.defaultModel ?? DeviceModels.MentraLive,
267
+ scanTimeoutMs: options.scanTimeoutMs,
268
+ })
269
+ const [galleryModeApplying, setGalleryModeApplying] = useState(false)
270
+ const [galleryModeError, setGalleryModeError] = useState<unknown | null>(null)
271
+
272
+ async function setGalleryMode(mode: GalleryMode) {
273
+ setGalleryModeApplying(true)
274
+ setGalleryModeError(null)
275
+ try {
276
+ await BluetoothSdk.setGalleryMode(mode)
277
+ } catch (error) {
278
+ setGalleryModeError(error)
279
+ options.onError?.(error)
280
+ throw error
281
+ } finally {
282
+ setGalleryModeApplying(false)
283
+ }
284
+ }
285
+
286
+ const galleryMode: GalleryModeState = {
287
+ applying: galleryModeApplying,
288
+ desired: connection.bluetoothStatus.galleryModeAuto === false ? "manual" : "auto",
289
+ error: galleryModeError,
290
+ }
291
+
292
+ return {
293
+ busy: connection.busy || galleryModeApplying,
294
+ clearDefaultDevice: connection.clearDefaultDevice,
295
+ connect: connection.connect,
296
+ connectDefault: connection.connectDefault,
297
+ defaultDevice: connection.defaultDevice,
298
+ disconnect: connection.disconnect,
299
+ error: galleryModeError ?? connection.error,
300
+ glasses: runtimeGlassesState(connection.glassesStatus),
301
+ refresh: connection.refresh,
302
+ scan: scanController(connection),
303
+ sdk: phoneSdkState(connection.bluetoothStatus, connection.defaultDevice, galleryMode),
304
+ setDefaultDevice: connection.setDefaultDevice,
305
+ setGalleryMode,
306
+ }
307
+ }