@mentra/bluetooth-sdk 0.1.20 → 0.1.21-beta.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 (114) hide show
  1. package/README.md +27 -12
  2. package/android/build.gradle +3 -0
  3. package/android/src/main/AndroidManifest.xml +3 -1
  4. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkAnalytics.kt +34 -0
  5. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkDefaults.kt +1 -0
  6. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +169 -26
  7. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +72 -16
  8. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +127 -8
  9. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +4 -0
  10. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +400 -99
  11. package/android/src/main/java/com/mentra/bluetoothsdk/MentraLocalNetworkModule.kt +333 -0
  12. package/android/src/main/java/com/mentra/bluetoothsdk/OtaManifest.kt +43 -3
  13. package/android/src/main/java/com/mentra/bluetoothsdk/camera/CameraModels.kt +18 -2
  14. package/android/src/main/java/com/mentra/bluetoothsdk/debug/BleTraceLogger.kt +1 -1
  15. package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +53 -0
  16. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Ar99.java +2653 -0
  17. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.kt +1 -1
  18. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +16 -9
  19. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.kt +1 -1
  20. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.kt +342 -42
  21. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1 -1
  22. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Nimo.kt +1 -1
  23. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +7 -2
  24. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +1 -1
  25. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/ar99/ota/Ar99OtaManager.java +566 -0
  26. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/ar99/ota/OtaByteUtils.java +18 -0
  27. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/ar99/ota/OtaCommandConstants.java +35 -0
  28. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/ar99/ota/OtaCrc32Util.java +13 -0
  29. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/ar99/ota/OtaGattTransport.java +11 -0
  30. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/ar99/ota/OtaProtocol.java +92 -0
  31. package/android/src/main/java/com/mentra/bluetoothsdk/status/WifiHotspotStatus.kt +19 -3
  32. package/android/src/main/java/com/mentra/bluetoothsdk/streaming/StreamModels.kt +52 -2
  33. package/android/src/main/java/com/mentra/bluetoothsdk/tts/TTSTools.kt +115 -47
  34. package/android/src/main/java/com/mentra/bluetoothsdk/types/DeviceModels.kt +7 -0
  35. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BleJsonCompact.java +8 -0
  36. package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +2 -1
  37. package/android/src/main/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitor.kt +45 -0
  38. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/Ar99OpusPcmDecoder.java +398 -0
  39. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PcmStreamPlayer.kt +328 -0
  40. package/android/src/test/java/com/mentra/bluetoothsdk/OtaManifestDowngradeTest.kt +86 -0
  41. package/android/src/test/java/com/mentra/bluetoothsdk/StreamStatusEventTest.kt +29 -0
  42. package/android/src/test/java/com/mentra/bluetoothsdk/camera/PhotoRequestTest.kt +45 -0
  43. package/android/src/test/java/com/mentra/bluetoothsdk/sgcs/Ar99AdvertisementMatcherTest.java +22 -0
  44. package/android/src/test/java/com/mentra/bluetoothsdk/utils/BleJsonCompactTest.java +20 -0
  45. package/android/src/test/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitorTest.kt +45 -0
  46. package/build/BluetoothSdk.types.d.ts +100 -22
  47. package/build/BluetoothSdk.types.d.ts.map +1 -1
  48. package/build/BluetoothSdk.types.js +2 -1
  49. package/build/BluetoothSdk.types.js.map +1 -1
  50. package/build/_internal.d.ts +3 -0
  51. package/build/_internal.d.ts.map +1 -1
  52. package/build/_internal.js +3 -0
  53. package/build/_internal.js.map +1 -1
  54. package/build/_private/BluetoothSdkModule.d.ts +31 -4
  55. package/build/_private/BluetoothSdkModule.d.ts.map +1 -1
  56. package/build/_private/BluetoothSdkModule.js +26 -3
  57. package/build/_private/BluetoothSdkModule.js.map +1 -1
  58. package/build/_private/MentraLocalNetworkModule.d.ts +37 -0
  59. package/build/_private/MentraLocalNetworkModule.d.ts.map +1 -0
  60. package/build/_private/MentraLocalNetworkModule.js +3 -0
  61. package/build/_private/MentraLocalNetworkModule.js.map +1 -0
  62. package/build/_private/cameraRequestPayload.d.ts +1 -1
  63. package/build/_private/cameraRequestPayload.d.ts.map +1 -1
  64. package/build/_private/cameraRequestPayload.js +7 -0
  65. package/build/_private/cameraRequestPayload.js.map +1 -1
  66. package/build/_private/photoRequestPayload.d.ts.map +1 -1
  67. package/build/_private/photoRequestPayload.js +10 -0
  68. package/build/_private/photoRequestPayload.js.map +1 -1
  69. package/build/_private/sdkOtaManifest.d.ts +20 -0
  70. package/build/_private/sdkOtaManifest.d.ts.map +1 -0
  71. package/build/_private/sdkOtaManifest.js +28 -0
  72. package/build/_private/sdkOtaManifest.js.map +1 -0
  73. package/build/index.d.ts +1 -1
  74. package/build/index.d.ts.map +1 -1
  75. package/build/index.js +11 -1
  76. package/build/index.js.map +1 -1
  77. package/expo-module.config.json +1 -0
  78. package/ios/BluetoothSdkModule.swift +113 -2
  79. package/ios/Source/BluetoothSdkDefaults.swift +2 -1
  80. package/ios/Source/Bridge.swift +87 -21
  81. package/ios/Source/DeviceManager.swift +118 -20
  82. package/ios/Source/DeviceStore.swift +4 -0
  83. package/ios/Source/MentraBluetoothSDK.swift +326 -33
  84. package/ios/Source/OtaManifest.swift +47 -4
  85. package/ios/Source/audio/PcmStreamPlayer.swift +410 -0
  86. package/ios/Source/camera/CameraModels.swift +26 -6
  87. package/ios/Source/internal/BleTraceLogger.swift +1 -1
  88. package/ios/Source/internal/BluetoothSdkAnalytics.swift +39 -0
  89. package/ios/Source/sgcs/Ar99.swift +2451 -0
  90. package/ios/Source/sgcs/G1.swift +1 -1
  91. package/ios/Source/sgcs/G2.swift +19 -7
  92. package/ios/Source/sgcs/Mach1.swift +1 -1
  93. package/ios/Source/sgcs/MentraLive.swift +478 -61
  94. package/ios/Source/sgcs/MentraNex.swift +1 -1
  95. package/ios/Source/sgcs/Nimo.swift +1 -1
  96. package/ios/Source/sgcs/SGCManager.swift +13 -2
  97. package/ios/Source/sgcs/Simulated.swift +1 -1
  98. package/ios/Source/sgcs/ar99/ota/Ar99OtaManager.swift +637 -0
  99. package/ios/Source/status/WifiHotspotStatus.swift +21 -2
  100. package/ios/Source/streaming/StreamModels.swift +68 -2
  101. package/ios/Source/tts/TTSTools.swift +1 -1
  102. package/ios/Source/types/DeviceModels.swift +13 -0
  103. package/ios/Source/utils/BleJsonCompact.swift +8 -0
  104. package/ios/Source/utils/Constants.swift +2 -0
  105. package/ios/Source/utils/PhoneAudioMonitor.swift +4 -0
  106. package/package.json +1 -2
  107. package/src/BluetoothSdk.types.ts +106 -24
  108. package/src/_internal.ts +3 -0
  109. package/src/_private/BluetoothSdkModule.ts +83 -18
  110. package/src/_private/MentraLocalNetworkModule.ts +50 -0
  111. package/src/_private/cameraRequestPayload.ts +9 -2
  112. package/src/_private/photoRequestPayload.ts +13 -4
  113. package/src/_private/sdkOtaManifest.ts +31 -0
  114. package/src/index.ts +13 -1
@@ -0,0 +1,37 @@
1
+ import { NativeModule } from "expo";
2
+ export type LocalNetworkResponse = {
3
+ status: number;
4
+ headers: Record<string, string>;
5
+ bodyBase64: string;
6
+ };
7
+ export type LocalNetworkDownloadResult = {
8
+ statusCode: number;
9
+ bytesWritten: number;
10
+ headers: Record<string, string>;
11
+ };
12
+ export type LocalNetworkDownloadProgress = {
13
+ requestId: string;
14
+ bytesWritten: number;
15
+ contentLength: number;
16
+ statusCode?: number;
17
+ headers?: Record<string, string>;
18
+ };
19
+ type LocalNetworkEvents = {
20
+ downloadProgress: (event: LocalNetworkDownloadProgress) => void;
21
+ networkLost: (event: {
22
+ ssid: string;
23
+ }) => void;
24
+ };
25
+ declare class MentraLocalNetworkNativeModule extends NativeModule<LocalNetworkEvents> {
26
+ connect(ssid: string, password: string): Promise<{
27
+ connected: boolean;
28
+ ssid: string;
29
+ }>;
30
+ request(requestId: string, url: string, method: string, headers: Record<string, string>, body: string | null, timeoutMs: number): Promise<LocalNetworkResponse>;
31
+ download(requestId: string, url: string, destination: string, headers: Record<string, string>, connectionTimeoutMs: number, readTimeoutMs: number): Promise<LocalNetworkDownloadResult>;
32
+ cancel(requestId: string): Promise<void>;
33
+ disconnect(): Promise<void>;
34
+ }
35
+ declare const _default: MentraLocalNetworkNativeModule | null;
36
+ export default _default;
37
+ //# sourceMappingURL=MentraLocalNetworkModule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraLocalNetworkModule.d.ts","sourceRoot":"","sources":["../../src/_private/MentraLocalNetworkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAA8B,MAAM,MAAM,CAAA;AAE9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,gBAAgB,EAAE,CAAC,KAAK,EAAE,4BAA4B,KAAK,IAAI,CAAA;IAC/D,WAAW,EAAE,CAAC,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,KAAK,IAAI,CAAA;CAC7C,CAAA;AAED,OAAO,OAAO,8BAA+B,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IACnF,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAAC;IACpF,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,oBAAoB,CAAC;IAChC,QAAQ,CACN,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,mBAAmB,EAAE,MAAM,EAC3B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,0BAA0B,CAAC;IACtC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IACxC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAC5B;;AAED,wBAAgG"}
@@ -0,0 +1,3 @@
1
+ import { requireOptionalNativeModule } from "expo";
2
+ export default requireOptionalNativeModule("MentraLocalNetwork");
3
+ //# sourceMappingURL=MentraLocalNetworkModule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MentraLocalNetworkModule.js","sourceRoot":"","sources":["../../src/_private/MentraLocalNetworkModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,2BAA2B,EAAC,MAAM,MAAM,CAAA;AAiD9D,eAAe,2BAA2B,CAAiC,oBAAoB,CAAC,CAAA","sourcesContent":["import {NativeModule, requireOptionalNativeModule} from \"expo\"\n\nexport type LocalNetworkResponse = {\n status: number\n headers: Record<string, string>\n bodyBase64: string\n}\n\nexport type LocalNetworkDownloadResult = {\n statusCode: number\n bytesWritten: number\n headers: Record<string, string>\n}\n\nexport type LocalNetworkDownloadProgress = {\n requestId: string\n bytesWritten: number\n contentLength: number\n statusCode?: number\n headers?: Record<string, string>\n}\n\ntype LocalNetworkEvents = {\n downloadProgress: (event: LocalNetworkDownloadProgress) => void\n networkLost: (event: {ssid: string}) => void\n}\n\ndeclare class MentraLocalNetworkNativeModule extends NativeModule<LocalNetworkEvents> {\n connect(ssid: string, password: string): Promise<{connected: boolean; ssid: string}>\n request(\n requestId: string,\n url: string,\n method: string,\n headers: Record<string, string>,\n body: string | null,\n timeoutMs: number,\n ): Promise<LocalNetworkResponse>\n download(\n requestId: string,\n url: string,\n destination: string,\n headers: Record<string, string>,\n connectionTimeoutMs: number,\n readTimeoutMs: number,\n ): Promise<LocalNetworkDownloadResult>\n cancel(requestId: string): Promise<void>\n disconnect(): Promise<void>\n}\n\nexport default requireOptionalNativeModule<MentraLocalNetworkNativeModule>(\"MentraLocalNetwork\")\n"]}
@@ -1,4 +1,4 @@
1
1
  import type { WarmUpCameraParams } from "../BluetoothSdk.types";
2
2
  /** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */
3
- export declare function warmUpCameraParamsForNative(params: WarmUpCameraParams): Record<string, string | number>;
3
+ export declare function warmUpCameraParamsForNative(params: WarmUpCameraParams): Record<string, string | number | boolean>;
4
4
  //# sourceMappingURL=cameraRequestPayload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cameraRequestPayload.d.ts","sourceRoot":"","sources":["../../src/_private/cameraRequestPayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAA;AAQ7D,kGAAkG;AAClG,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAiBjC"}
1
+ {"version":3,"file":"cameraRequestPayload.d.ts","sourceRoot":"","sources":["../../src/_private/cameraRequestPayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,uBAAuB,CAAA;AAQ7D,kGAAkG;AAClG,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAwB3C"}
@@ -7,6 +7,7 @@ function nonBlankString(value) {
7
7
  export function warmUpCameraParamsForNative(params) {
8
8
  const payload = {
9
9
  size: normalizePhotoSizeTier(params.size),
10
+ mode: params.mode ?? "photo",
10
11
  };
11
12
  const requestId = nonBlankString(params.requestId);
12
13
  if (requestId != null) {
@@ -20,6 +21,12 @@ export function warmUpCameraParamsForNative(params) {
20
21
  if (durationMs != null && Number.isFinite(durationMs) && durationMs > 0) {
21
22
  payload.durationMs = Math.round(durationMs);
22
23
  }
24
+ if (params.mfnr != null) {
25
+ payload.mfnr = params.mfnr;
26
+ }
27
+ if (params.zsl != null) {
28
+ payload.zsl = params.zsl;
29
+ }
23
30
  return payload;
24
31
  }
25
32
  //# sourceMappingURL=cameraRequestPayload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cameraRequestPayload.js","sourceRoot":"","sources":["../../src/_private/cameraRequestPayload.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,sBAAsB,EAAC,MAAM,uBAAuB,CAAA;AAE5D,SAAS,cAAc,CAAC,KAAqB;IAC3C,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;IAC7B,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,2BAA2B,CACzC,MAA0B;IAE1B,MAAM,OAAO,GAAoC;QAC/C,IAAI,EAAE,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC;KAC1C,CAAA;IACD,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAClD,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAA;IAC/B,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,CAAA;IAC5C,IAAI,cAAc,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACpF,OAAO,CAAC,cAAc,GAAG,cAAc,CAAA;IACzC,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;IACpC,IAAI,UAAU,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC","sourcesContent":["import type {WarmUpCameraParams} from \"../BluetoothSdk.types\"\nimport {normalizePhotoSizeTier} from \"./photoRequestPayload\"\n\nfunction nonBlankString(value?: string | null): string | undefined {\n const trimmed = value?.trim()\n return trimmed && trimmed.length > 0 ? trimmed : undefined\n}\n\n/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */\nexport function warmUpCameraParamsForNative(\n params: WarmUpCameraParams,\n): Record<string, string | number> {\n const payload: Record<string, string | number> = {\n size: normalizePhotoSizeTier(params.size),\n }\n const requestId = nonBlankString(params.requestId)\n if (requestId != null) {\n payload.requestId = requestId\n }\n const exposureTimeNs = params.exposureTimeNs\n if (exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0) {\n payload.exposureTimeNs = exposureTimeNs\n }\n const durationMs = params.durationMs\n if (durationMs != null && Number.isFinite(durationMs) && durationMs > 0) {\n payload.durationMs = Math.round(durationMs)\n }\n return payload\n}\n"]}
1
+ {"version":3,"file":"cameraRequestPayload.js","sourceRoot":"","sources":["../../src/_private/cameraRequestPayload.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,sBAAsB,EAAC,MAAM,uBAAuB,CAAA;AAE5D,SAAS,cAAc,CAAC,KAAqB;IAC3C,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAA;IAC7B,OAAO,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,2BAA2B,CACzC,MAA0B;IAE1B,MAAM,OAAO,GAA8C;QACzD,IAAI,EAAE,sBAAsB,CAAC,MAAM,CAAC,IAAI,CAAC;QACzC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,OAAO;KAC7B,CAAA;IACD,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAClD,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACtB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAA;IAC/B,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,CAAA;IAC5C,IAAI,cAAc,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACpF,OAAO,CAAC,cAAc,GAAG,cAAc,CAAA;IACzC,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAA;IACpC,IAAI,UAAU,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACxE,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IAC7C,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;IAC5B,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAA;IAC1B,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC","sourcesContent":["import type {WarmUpCameraParams} from \"../BluetoothSdk.types\"\nimport {normalizePhotoSizeTier} from \"./photoRequestPayload\"\n\nfunction nonBlankString(value?: string | null): string | undefined {\n const trimmed = value?.trim()\n return trimmed && trimmed.length > 0 ? trimmed : undefined\n}\n\n/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */\nexport function warmUpCameraParamsForNative(\n params: WarmUpCameraParams,\n): Record<string, string | number | boolean> {\n const payload: Record<string, string | number | boolean> = {\n size: normalizePhotoSizeTier(params.size),\n mode: params.mode ?? \"photo\",\n }\n const requestId = nonBlankString(params.requestId)\n if (requestId != null) {\n payload.requestId = requestId\n }\n const exposureTimeNs = params.exposureTimeNs\n if (exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0) {\n payload.exposureTimeNs = exposureTimeNs\n }\n const durationMs = params.durationMs\n if (durationMs != null && Number.isFinite(durationMs) && durationMs > 0) {\n payload.durationMs = Math.round(durationMs)\n }\n if (params.mfnr != null) {\n payload.mfnr = params.mfnr\n }\n if (params.zsl != null) {\n payload.zsl = params.zsl\n }\n return payload\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"photoRequestPayload.d.ts","sourceRoot":"","sources":["../../src/_private/photoRequestPayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAE,SAAS,EAAC,MAAM,uBAAuB,CAAA;AAExE,mEAAmE;AACnE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAgB1E;AAOD,kGAAkG;AAClG,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,kBAAkB,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAmD3C"}
1
+ {"version":3,"file":"photoRequestPayload.d.ts","sourceRoot":"","sources":["../../src/_private/photoRequestPayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAE,SAAS,EAAsB,MAAM,uBAAuB,CAAA;AAY7F,mEAAmE;AACnE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAgB1E;AAOD,kGAAkG;AAClG,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAoDjH"}
@@ -1,3 +1,12 @@
1
+ const PHOTO_TRANSFER_METHODS = new Set(["auto", "direct", "ble"]);
2
+ function photoTransferMethodForNative(value) {
3
+ if (value === undefined)
4
+ return "auto";
5
+ if (typeof value === "string" && PHOTO_TRANSFER_METHODS.has(value)) {
6
+ return value;
7
+ }
8
+ throw new TypeError(`Invalid transferMethod ${JSON.stringify(value)}. Expected "auto", "direct", or "ble".`);
9
+ }
1
10
  /** Maps unknown/legacy size strings to the current wire format. */
2
11
  export function normalizePhotoSizeTier(size) {
3
12
  switch (size) {
@@ -25,6 +34,7 @@ export function photoRequestParamsForNative(params) {
25
34
  const payload = {
26
35
  size: normalizePhotoSizeTier(params.size),
27
36
  mode: params.mode ?? "photo",
37
+ transferMethod: photoTransferMethodForNative(params.transferMethod),
28
38
  webhookUrl: params.webhookUrl ?? "",
29
39
  compress: params.compress,
30
40
  sound: params.sound,
@@ -1 +1 @@
1
- {"version":3,"file":"photoRequestPayload.js","sourceRoot":"","sources":["../../src/_private/photoRequestPayload.ts"],"names":[],"mappings":"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","sourcesContent":["import type {PhotoRequestParams, PhotoSize} from \"../BluetoothSdk.types\"\n\n/** Maps unknown/legacy size strings to the current wire format. */\nexport function normalizePhotoSizeTier(size: string | undefined): PhotoSize {\n switch (size) {\n case \"small\":\n return \"low\"\n case \"large\":\n return \"high\"\n case \"full\":\n return \"max\"\n case \"low\":\n case \"medium\":\n case \"high\":\n case \"max\":\n return size\n default:\n return \"medium\"\n }\n}\n\nfunction nonBlankString(value?: string | null): string | undefined {\n const trimmed = value?.trim()\n return trimmed && trimmed.length > 0 ? trimmed : undefined\n}\n\n/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */\nexport function photoRequestParamsForNative(\n params: PhotoRequestParams,\n): Record<string, string | number | boolean> {\n const payload: Record<string, string | number | boolean> = {\n size: normalizePhotoSizeTier(params.size),\n mode: params.mode ?? \"photo\",\n webhookUrl: params.webhookUrl ?? \"\",\n compress: params.compress,\n sound: params.sound,\n }\n const requestId = nonBlankString(params.requestId)\n if (requestId != null) {\n payload.requestId = requestId\n }\n if (params.save != null) {\n payload.save = params.save\n }\n if (params.authToken != null && params.authToken.length > 0) {\n payload.authToken = params.authToken\n }\n const exposureTimeNs = params.exposureTimeNs\n const hasManualExposure = exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0\n if (hasManualExposure) {\n payload.exposureTimeNs = exposureTimeNs\n }\n if (hasManualExposure && params.iso != null && Number.isFinite(params.iso) && params.iso > 0) {\n payload.iso = Math.round(params.iso)\n }\n if (params.aeExposureDivisor != null && params.aeExposureDivisor > 1) {\n payload.aeExposureDivisor = Math.round(params.aeExposureDivisor)\n }\n if (params.isoCap != null && params.isoCap > 0) {\n payload.isoCap = Math.round(params.isoCap)\n }\n if (params.noiseReduction != null) {\n payload.noiseReduction = params.noiseReduction\n }\n if (params.edgeEnhancement != null) {\n payload.edgeEnhancement = params.edgeEnhancement\n }\n if (params.mfnr != null) {\n payload.mfnr = params.mfnr\n }\n if (params.zsl != null) {\n payload.zsl = params.zsl\n }\n if (params.ispDigitalGain != null) {\n payload.ispDigitalGain = Math.round(params.ispDigitalGain)\n }\n if (params.ispAnalogGain != null && params.ispAnalogGain.length > 0) {\n payload.ispAnalogGain = params.ispAnalogGain\n }\n return payload\n}\n"]}
1
+ {"version":3,"file":"photoRequestPayload.js","sourceRoot":"","sources":["../../src/_private/photoRequestPayload.ts"],"names":[],"mappings":"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","sourcesContent":["import type {PhotoRequestParams, PhotoSize, PhotoTransferMethod} from \"../BluetoothSdk.types\"\n\nconst PHOTO_TRANSFER_METHODS = new Set<PhotoTransferMethod>([\"auto\", \"direct\", \"ble\"])\n\nfunction photoTransferMethodForNative(value: unknown): PhotoTransferMethod {\n if (value === undefined) return \"auto\"\n if (typeof value === \"string\" && PHOTO_TRANSFER_METHODS.has(value as PhotoTransferMethod)) {\n return value as PhotoTransferMethod\n }\n throw new TypeError(`Invalid transferMethod ${JSON.stringify(value)}. Expected \"auto\", \"direct\", or \"ble\".`)\n}\n\n/** Maps unknown/legacy size strings to the current wire format. */\nexport function normalizePhotoSizeTier(size: string | undefined): PhotoSize {\n switch (size) {\n case \"small\":\n return \"low\"\n case \"large\":\n return \"high\"\n case \"full\":\n return \"max\"\n case \"low\":\n case \"medium\":\n case \"high\":\n case \"max\":\n return size\n default:\n return \"medium\"\n }\n}\n\nfunction nonBlankString(value?: string | null): string | undefined {\n const trimmed = value?.trim()\n return trimmed && trimmed.length > 0 ? trimmed : undefined\n}\n\n/** Expo Android bridge rejects null values in Map<String, Any> — omit optional nullish fields. */\nexport function photoRequestParamsForNative(params: PhotoRequestParams): Record<string, string | number | boolean> {\n const payload: Record<string, string | number | boolean> = {\n size: normalizePhotoSizeTier(params.size),\n mode: params.mode ?? \"photo\",\n transferMethod: photoTransferMethodForNative(params.transferMethod),\n webhookUrl: params.webhookUrl ?? \"\",\n compress: params.compress,\n sound: params.sound,\n }\n const requestId = nonBlankString(params.requestId)\n if (requestId != null) {\n payload.requestId = requestId\n }\n if (params.save != null) {\n payload.save = params.save\n }\n if (params.authToken != null && params.authToken.length > 0) {\n payload.authToken = params.authToken\n }\n const exposureTimeNs = params.exposureTimeNs\n const hasManualExposure = exposureTimeNs != null && Number.isFinite(exposureTimeNs) && exposureTimeNs > 0\n if (hasManualExposure) {\n payload.exposureTimeNs = exposureTimeNs\n }\n if (hasManualExposure && params.iso != null && Number.isFinite(params.iso) && params.iso > 0) {\n payload.iso = Math.round(params.iso)\n }\n if (params.aeExposureDivisor != null && params.aeExposureDivisor > 1) {\n payload.aeExposureDivisor = Math.round(params.aeExposureDivisor)\n }\n if (params.isoCap != null && params.isoCap > 0) {\n payload.isoCap = Math.round(params.isoCap)\n }\n if (params.noiseReduction != null) {\n payload.noiseReduction = params.noiseReduction\n }\n if (params.edgeEnhancement != null) {\n payload.edgeEnhancement = params.edgeEnhancement\n }\n if (params.mfnr != null) {\n payload.mfnr = params.mfnr\n }\n if (params.zsl != null) {\n payload.zsl = params.zsl\n }\n if (params.ispDigitalGain != null) {\n payload.ispDigitalGain = Math.round(params.ispDigitalGain)\n }\n if (params.ispAnalogGain != null && params.ispAnalogGain.length > 0) {\n payload.ispAnalogGain = params.ispAnalogGain\n }\n return payload\n}\n"]}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * SDK-pinned OTA manifest URL derivation.
3
+ *
4
+ * Each Bluetooth SDK release publishes an immutable manifest
5
+ * (`bluetooth-sdk-<version>-version.json`) pinning the exact ASG artifact paired with that SDK
6
+ * version. The URL is derived from this package's own version — the version is frozen into the
7
+ * published artifact, so this is equivalent to baking the URL at release time while keeping the
8
+ * manifest itself replaceable as an operational escape hatch (asset moves, CDN migration).
9
+ *
10
+ * Mirrors the native derivation in `OtaManifestDefaults.defaultOtaVersionUrl()` (Kotlin) /
11
+ * `BluetoothSdkDefaults` (Swift).
12
+ */
13
+ /** This Bluetooth SDK package's own version, as published. */
14
+ export declare const BLUETOOTH_SDK_VERSION: string;
15
+ /**
16
+ * The immutable manifest URL pinning the ASG artifact paired with this SDK version, or null when
17
+ * the package version is unavailable (malformed workspace state).
18
+ */
19
+ export declare function sdkPinnedOtaManifestUrl(): string | null;
20
+ //# sourceMappingURL=sdkOtaManifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdkOtaManifest.d.ts","sourceRoot":"","sources":["../../src/_private/sdkOtaManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,EAAE,MAA2C,CAAA;AAE/E;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAKvD"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * SDK-pinned OTA manifest URL derivation.
3
+ *
4
+ * Each Bluetooth SDK release publishes an immutable manifest
5
+ * (`bluetooth-sdk-<version>-version.json`) pinning the exact ASG artifact paired with that SDK
6
+ * version. The URL is derived from this package's own version — the version is frozen into the
7
+ * published artifact, so this is equivalent to baking the URL at release time while keeping the
8
+ * manifest itself replaceable as an operational escape hatch (asset moves, CDN migration).
9
+ *
10
+ * Mirrors the native derivation in `OtaManifestDefaults.defaultOtaVersionUrl()` (Kotlin) /
11
+ * `BluetoothSdkDefaults` (Swift).
12
+ */
13
+ const SDK_OTA_RELEASE_BASE_URL = "https://github.com/Mentra-Community/MentraOS/releases/download/bluetooth-sdk-ota";
14
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
15
+ const packageJson = require("../../package.json");
16
+ /** This Bluetooth SDK package's own version, as published. */
17
+ export const BLUETOOTH_SDK_VERSION = (packageJson.version ?? "").trim();
18
+ /**
19
+ * The immutable manifest URL pinning the ASG artifact paired with this SDK version, or null when
20
+ * the package version is unavailable (malformed workspace state).
21
+ */
22
+ export function sdkPinnedOtaManifestUrl() {
23
+ if (!BLUETOOTH_SDK_VERSION) {
24
+ return null;
25
+ }
26
+ return `${SDK_OTA_RELEASE_BASE_URL}/bluetooth-sdk-${BLUETOOTH_SDK_VERSION}-version.json`;
27
+ }
28
+ //# sourceMappingURL=sdkOtaManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdkOtaManifest.js","sourceRoot":"","sources":["../../src/_private/sdkOtaManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,wBAAwB,GAAG,kFAAkF,CAAA;AAEnH,8DAA8D;AAC9D,MAAM,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAuB,CAAA;AAEvE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAW,CAAC,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;AAE/E;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,GAAG,wBAAwB,kBAAkB,qBAAqB,eAAe,CAAA;AAC1F,CAAC","sourcesContent":["/**\n * SDK-pinned OTA manifest URL derivation.\n *\n * Each Bluetooth SDK release publishes an immutable manifest\n * (`bluetooth-sdk-<version>-version.json`) pinning the exact ASG artifact paired with that SDK\n * version. The URL is derived from this package's own version — the version is frozen into the\n * published artifact, so this is equivalent to baking the URL at release time while keeping the\n * manifest itself replaceable as an operational escape hatch (asset moves, CDN migration).\n *\n * Mirrors the native derivation in `OtaManifestDefaults.defaultOtaVersionUrl()` (Kotlin) /\n * `BluetoothSdkDefaults` (Swift).\n */\n\nconst SDK_OTA_RELEASE_BASE_URL = \"https://github.com/Mentra-Community/MentraOS/releases/download/bluetooth-sdk-ota\"\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst packageJson = require(\"../../package.json\") as {version?: string}\n\n/** This Bluetooth SDK package's own version, as published. */\nexport const BLUETOOTH_SDK_VERSION: string = (packageJson.version ?? \"\").trim()\n\n/**\n * The immutable manifest URL pinning the ASG artifact paired with this SDK version, or null when\n * the package version is unavailable (malformed workspace state).\n */\nexport function sdkPinnedOtaManifestUrl(): string | null {\n if (!BLUETOOTH_SDK_VERSION) {\n return null\n }\n return `${SDK_OTA_RELEASE_BASE_URL}/bluetooth-sdk-${BLUETOOTH_SDK_VERSION}-version.json`\n}\n"]}
package/build/index.d.ts CHANGED
@@ -2,5 +2,5 @@ import type { BluetoothSdkPublicModule } from "./BluetoothSdk.types";
2
2
  export declare const BluetoothSdk: BluetoothSdkPublicModule;
3
3
  export default BluetoothSdk;
4
4
  export { CAMERA_FOV_DEFAULT, CAMERA_FOV_MAX, CAMERA_FOV_MIN, DeviceModels, isBusyGlassesConnectionStatus, isConnectedGlassesConnectionStatus, isConnectedWifiStatus, isEnabledHotspotStatus, isReadyGlassesConnectionStatus, } from "./BluetoothSdk.types";
5
- export type { AccelEvent, AudioConnectedEvent, AudioDisconnectedEvent, AudioPairingNeededEvent, BatteryStatusEvent, BluetoothSdkEvent, BluetoothSdkEventListener, BluetoothSdkEventMap, BluetoothSdkEventName, BluetoothSdkPublicModule as BluetoothSdkModule, BluetoothSdkSubscription, ButtonPhotoSize, PhotoCaptureDefaults, ButtonPressEvent, CameraFovPreset, CameraFovRequest, CameraFovResult, CameraRoiPosition, CompatibleGlassesSearchStopEvent, ConnectOptions, ConnectedGlassesConnectionStatus, ConnectedWifiStatus, Device, DeviceModel, EnabledHotspotStatus, GalleryStatusEvent, GlassesConnectionStatus, GlassesMediaVolumeGetResult, GlassesMediaVolumeSetResult, GlassesNotReadyEvent, HeadUpEvent, HotspotErrorEvent, HotspotStatus, HotspotStatusChangeEvent, LocalTranscriptionEvent, LogEvent, MicLc3Event, MicMode, MicPcmEvent, MicPreference, OtaStartAckEvent, OtaStatus, OtaStatusEvent, OtaQueryResult, PairFailureEvent, PhotoCaptureMetadata, PhotoResolvedConfig, PhotoCompression, PhotoFpsRange, PhotoMeteredPreview, PhotoMode, PhotoResponseEvent, PhotoRequestedCaptureConfig, PhotoRequestParams, PhotoSize, PhotoStatusEvent, PhotoStatusState, PhotoSuccessResponseEvent, RgbLedAction, RgbLedColor, RgbLedControlResponseEvent, RgbLedControlSuccessResponseEvent, ScanModelOptions, ScanOptions, ScanResultsCallback, SpeakingStatusEvent, SettingsAckEvent, SettingsAckSetting, SettingsAckSuccessEvent, SettingsAckSuccessStatus, SettingsAckStatus, StreamAudioConfig, StreamResolvedConfig, StreamStartRequest, StreamStatusEvent, StreamStatusLifecycleState, StreamStatusReconnectState, StreamStatusState, StreamVideoConfig, SwipeVolumeStatusEvent, SwitchStatusEvent, TouchEvent, VideoRecordingDefaults, VideoRecordingStartedStatusEvent, VideoRecordingStatusEvent, VideoRecordingStatusState, VideoRecordingStoppedStatusEvent, VideoRecordingSuccessStatusEvent, VersionInfoEvent, VersionInfoResult, WifiScanResultEvent, VoiceActivityDetectionStatusEvent, WifiSearchResult, WifiStatus, WifiStatusChangeEvent, } from "./BluetoothSdk.types";
5
+ export type { AccelEvent, Ar99OtaStatusEvent, AudioConnectedEvent, AudioDisconnectedEvent, AudioPairingNeededEvent, BatteryStatusEvent, BluetoothSdkEvent, BluetoothSdkEventListener, BluetoothSdkEventMap, BluetoothSdkEventName, BluetoothSdkPublicModule as BluetoothSdkModule, BluetoothSdkSubscription, ButtonPhotoSize, PhotoCaptureDefaults, ButtonPressEvent, CameraFovPreset, CameraFovRequest, CameraFovResult, CameraRoiPosition, CompatibleGlassesSearchStopEvent, ConnectOptions, ConnectedGlassesConnectionStatus, ConnectedWifiStatus, Device, DeviceModel, EnabledHotspotStatus, GalleryStatusEvent, GlassesConnectionStatus, GlassesMediaVolumeGetResult, GlassesMediaVolumeSetResult, GlassesNotReadyEvent, HeadUpEvent, HotspotErrorEvent, HotspotStatus, HotspotStatusChangeEvent, LocalTranscriptionEvent, LogEvent, MicLc3Event, MicMode, MicPcmEvent, MicPreference, OtaStartAckEvent, OtaStatus, OtaStatusEvent, OtaQueryResult, PairFailureEvent, PhotoCaptureMetadata, PhotoResolvedConfig, PhotoCompression, PhotoFpsRange, PhotoMeteredPreview, PhotoMode, PhotoTransferMethod, PhotoResponseEvent, PhotoRequestedCaptureConfig, PhotoRequestParams, PhotoSize, PhotoStatusEvent, PhotoStatusState, PhotoSuccessResponseEvent, RgbLedAction, RgbLedColor, RgbLedControlResponseEvent, RgbLedControlSuccessResponseEvent, ScanModelOptions, ScanOptions, ScanResultsCallback, SpeakingStatusEvent, SettingsAckEvent, SettingsAckSetting, SettingsAckSuccessEvent, SettingsAckSuccessStatus, SettingsAckStatus, StreamAudioConfig, StreamResolvedConfig, StreamStartRequest, StreamStatusEvent, StreamStatusLifecycleState, StreamStatusReconnectState, StreamStatusState, StreamVideoConfig, SwipeVolumeStatusEvent, SwitchStatusEvent, TouchEvent, VideoRecordingDefaults, VideoRecordingStartedStatusEvent, VideoRecordingStatusEvent, VideoRecordingStatusState, VideoRecordingStoppedStatusEvent, VideoRecordingSuccessStatusEvent, VersionInfoEvent, VersionInfoResult, WifiScanResultEvent, VoiceActivityDetectionStatusEvent, WifiSearchResult, WifiStatus, WifiStatusChangeEvent, } from "./BluetoothSdk.types";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,wBAAwB,EAEzB,MAAM,sBAAsB,CAAA;AAkE7B,eAAO,MAAM,YAAY,EAAE,wBAwEzB,CAAA;AAEF,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,IAAI,kBAAkB,EAC9C,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EACd,gCAAgC,EAChC,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,iCAAiC,EACjC,gBAAgB,EAChB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,gCAAgC,EAChC,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,gCAAgC,EAChC,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,iCAAiC,EACjC,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,wBAAwB,EAEzB,MAAM,sBAAsB,CAAA;AAmE7B,eAAO,MAAM,YAAY,EAAE,wBAiFzB,CAAA;AAEF,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,IAAI,kBAAkB,EAC9C,wBAAwB,EACxB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,gCAAgC,EAChC,cAAc,EACd,gCAAgC,EAChC,mBAAmB,EACnB,MAAM,EACN,WAAW,EACX,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,oBAAoB,EACpB,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,OAAO,EACP,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,SAAS,EACT,mBAAmB,EACnB,kBAAkB,EAClB,2BAA2B,EAC3B,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,YAAY,EACZ,WAAW,EACX,0BAA0B,EAC1B,iCAAiC,EACjC,gBAAgB,EAChB,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,EAC1B,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,iBAAiB,EACjB,UAAU,EACV,sBAAsB,EACtB,gCAAgC,EAChC,yBAAyB,EACzB,yBAAyB,EACzB,gCAAgC,EAChC,gCAAgC,EAChC,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,iCAAiC,EACjC,gBAAgB,EAChB,UAAU,EACV,qBAAqB,GACtB,MAAM,sBAAsB,CAAA"}
package/build/index.js CHANGED
@@ -37,6 +37,7 @@ const PUBLIC_EVENT_NAMES = new Set([
37
37
  "stream_status",
38
38
  "ota_start_ack",
39
39
  "ota_status",
40
+ "ar99_ota_status",
40
41
  "version_info",
41
42
  "extraction_progress",
42
43
  ]);
@@ -84,9 +85,10 @@ export const BluetoothSdk = Object.freeze({
84
85
  setHotspotState: bindPublicMethod("setHotspotState"),
85
86
  setGalleryModeEnabled: bindPublicMethod("setGalleryModeEnabled"),
86
87
  setVoiceActivityDetectionEnabled: bindPublicMethod("setVoiceActivityDetectionEnabled"),
88
+ setLoudnessGateEnabled: bindPublicMethod("setLoudnessGateEnabled"),
87
89
  /**
88
90
  * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request
89
- * `requestPhoto(...)` options (e.g. `mode: "text"` for AE ÷3, or explicit per-shot
91
+ * `requestPhoto(...)` options (e.g. `mode: "text"` for text sensor size/crop, or explicit per-shot
90
92
  * fields). Still functional until removed in a future release.
91
93
  */
92
94
  setPhotoCaptureDefaults: bindPublicMethod("setPhotoCaptureDefaults"),
@@ -99,10 +101,14 @@ export const BluetoothSdk = Object.freeze({
99
101
  },
100
102
  setMaxVideoRecordingDuration: bindPublicMethod("setMaxVideoRecordingDuration"),
101
103
  setCameraFov: bindPublicMethod("setCameraFov"),
104
+ setLegacyCameraFov: bindPublicMethod("setLegacyCameraFov"),
105
+ setCameraFovOverride: bindPublicMethod("setCameraFovOverride"),
106
+ releaseCameraFovOverride: bindPublicMethod("releaseCameraFovOverride"),
102
107
  setCameraTuningConfig: bindPublicMethod("setCameraTuningConfig"),
103
108
  queryGalleryStatus: bindPublicMethod("queryGalleryStatus"),
104
109
  requestPhoto: bindPublicMethod("requestPhoto"),
105
110
  warmUpCamera: bindPublicMethod("warmUpCamera"),
111
+ stopCameraWarmUp: bindPublicMethod("stopCameraWarmUp"),
106
112
  startVideoRecording: bindPublicMethod("startVideoRecording"),
107
113
  stopVideoRecording: bindPublicMethod("stopVideoRecording"),
108
114
  startStream: bindPublicMethod("startStream"),
@@ -116,6 +122,10 @@ export const BluetoothSdk = Object.freeze({
116
122
  requestVersionInfo: bindPublicMethod("requestVersionInfo"),
117
123
  checkForOtaUpdate: bindPublicMethod("checkForOtaUpdate"),
118
124
  startOtaUpdate,
125
+ startAr99OtaFromFile: bindPublicMethod("startAr99OtaFromFile"),
126
+ cancelAr99Ota: bindPublicMethod("cancelAr99Ota"),
127
+ sendAr99FactoryReset: bindPublicMethod("sendAr99FactoryReset"),
128
+ buildAr99OtaSignature: bindPublicMethod("buildAr99OtaSignature"),
119
129
  setSttModelDetails: bindPublicMethod("setSttModelDetails"),
120
130
  getSttModelPath: bindPublicMethod("getSttModelPath"),
121
131
  checkSttModelAvailable: bindPublicMethod("checkSttModelAvailable"),
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,yBAAyB,MAAM,+BAA+B,CAAA;AAQrE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAwB;IACxD,KAAK;IACL,mBAAmB;IACnB,wBAAwB;IACxB,mBAAmB;IACnB,cAAc;IACd,aAAa;IACb,aAAa;IACb,SAAS;IACT,iCAAiC;IACjC,iBAAiB;IACjB,gBAAgB;IAChB,qBAAqB;IACrB,oBAAoB;IACpB,kBAAkB;IAClB,uBAAuB;IACvB,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,wBAAwB;IACxB,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,gCAAgC;IAChC,qBAAqB;IACrB,eAAe;IACf,0BAA0B;IAC1B,cAAc;IACd,cAAc;IACd,sBAAsB;IACtB,iBAAiB;IACjB,oBAAoB;IACpB,SAAS;IACT,SAAS;IACT,eAAe;IACf,eAAe;IACf,YAAY;IACZ,cAAc;IACd,qBAAqB;CACtB,CAAC,CAAA;AAEF,MAAM,WAAW,GAA4C,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;IACnF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,mCAAmC,SAAS,sDAAsD,CAAC,CAAA;IACrH,CAAC;IACD,OAAO,yBAAyB,CAAC,WAAW,CAAC,SAAS,EAAE,QAA4D,CAAC,CAAA;AACvH,CAAC,CAAA;AAED,MAAM,cAAc,GAA+C,GAAG,EAAE;IACtE,OAAO,yBAAyB,CAAC,cAAc,EAAE,CAAA;AACnD,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAA2C,IAAO,EAA+B,EAAE;IAC1G,MAAM,MAAM,GAAI,yBAAgE,CAAC,IAAI,CAAC,CAAA;IACtF,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAgC,CAAA;IAC9E,CAAC;IAED,OAAO,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,IAAI,KAAK,CAAC,gBAAgB,MAAM,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;IACzG,CAAC,CAA2C,CAAA;AAC9C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAA6B,MAAM,CAAC,MAAM,CAAC;IAClE,WAAW;IACX,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC;IACtD,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC;IACtD,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC;IACxC,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC;IACtC,IAAI,EAAE,gBAAgB,CAAC,MAAM,CAAqC;IAClE,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IACpC,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC;IAClD,uBAAuB,EAAE,gBAAgB,CAAC,yBAAyB,CAAC;IACpE,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC;IAC1C,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC;IAClC,WAAW,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAC5C,YAAY,EAAE,gBAAgB,CAAC,cAAc,CAAC;IAC9C,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC;IAChD,oBAAoB,EAAE,gBAAgB,CAAC,sBAAsB,CAAC;IAC9D,cAAc,EAAE,gBAAgB,CAAC,gBAAgB,CAAC;IAClD,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC;IAChD,iBAAiB,EAAE,gBAAgB,CAAC,mBAAmB,CAAC;IACxD,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC;IACpD,mBAAmB,EAAE,gBAAgB,CAAC,qBAAqB,CAAC;IAC5D,iBAAiB,EAAE,gBAAgB,CAAC,mBAAmB,CAAC;IACxD,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC;IACpD,qBAAqB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,gCAAgC,EAAE,gBAAgB,CAAC,kCAAkC,CAAC;IACtF;;;;OAIG;IACH,uBAAuB,EAAE,gBAAgB,CAAC,yBAAyB,CAAC;IACpE,yBAAyB,EAAE,CAAC,EAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAyB,EAAE,EAAE;QAC1E,MAAM,MAAM,GAAI,yBAAgE,CAAC,yBAAyB,CAAA;QAC1G,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,OAAO,OAAO,CAAC,MAAM,CACnB,IAAI,KAAK,CAAC,gGAAgG,CAAC,CAC5G,CAAA;QACH,CAAC;QACD,OAAO,yBAAyB,CAAC,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IAChF,CAAC;IACD,4BAA4B,EAAE,gBAAgB,CAAC,8BAA8B,CAAC;IAC9E,YAAY,EAAE,gBAAgB,CAAC,cAAc,CAAC;IAC9C,qBAAqB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,YAAY,EAAE,gBAAgB,CAAC,cAAc,CAAC;IAC9C,YAAY,EAAE,gBAAgB,CAAC,cAAc,CAAC;IAC9C,mBAAmB,EAAE,gBAAgB,CAAC,qBAAqB,CAAC;IAC5D,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,WAAW,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAC5C,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC;IAC1C,WAAW,EAAE,gBAAgB,CAAC,aAAa,CAAC;IAC5C,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC;IACpD,qBAAqB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,qBAAqB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,qBAAqB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAChE,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC;IAChD,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,iBAAiB,EAAE,gBAAgB,CAAC,mBAAmB,CAAC;IACxD,cAAc;IACd,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC;IACpD,sBAAsB,EAAE,gBAAgB,CAAC,wBAAwB,CAAC;IAClE,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC;IACtD,aAAa,EAAE,gBAAgB,CAAC,eAAe,CAAC;IAChD,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,kBAAkB,EAAE,gBAAgB,CAAC,oBAAoB,CAAC;IAC1D,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC;IACpD,mBAAmB,EAAE,gBAAgB,CAAC,qBAAqB,CAAC;IAC5D,sBAAsB,EAAE,gBAAgB,CAAC,wBAAwB,CAAC;IAClE,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC;IACtD,gBAAgB,EAAE,gBAAgB,CAAC,kBAAkB,CAAC;CACvD,CAAC,CAAA;AAEF,eAAe,YAAY,CAAA;AAE3B,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,YAAY,EACZ,6BAA6B,EAC7B,kCAAkC,EAClC,qBAAqB,EACrB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,sBAAsB,CAAA","sourcesContent":["import PrivateBluetoothSdkModule from \"./_private/BluetoothSdkModule\"\nimport type {\n BluetoothSdkEventListener,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule,\n VideoRecordingDefaults,\n} from \"./BluetoothSdk.types\"\n\nconst PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([\n \"log\",\n \"device_discovered\",\n \"default_device_changed\",\n \"glasses_not_ready\",\n \"button_press\",\n \"touch_event\",\n \"accel_event\",\n \"head_up\",\n \"voice_activity_detection_status\",\n \"speaking_status\",\n \"battery_status\",\n \"local_transcription\",\n \"wifi_status_change\",\n \"wifi_scan_result\",\n \"hotspot_status_change\",\n \"hotspot_error\",\n \"photo_response\",\n \"photo_status\",\n \"camera_status\",\n \"video_recording_status\",\n \"media_success\",\n \"media_error\",\n \"gallery_status\",\n \"compatible_glasses_search_stop\",\n \"swipe_volume_status\",\n \"switch_status\",\n \"rgb_led_control_response\",\n \"settings_ack\",\n \"pair_failure\",\n \"audio_pairing_needed\",\n \"audio_connected\",\n \"audio_disconnected\",\n \"mic_pcm\",\n \"mic_lc3\",\n \"stream_status\",\n \"ota_start_ack\",\n \"ota_status\",\n \"version_info\",\n \"extraction_progress\",\n])\n\nconst addListener: BluetoothSdkPublicModule[\"addListener\"] = (eventName, listener) => {\n if (!PUBLIC_EVENT_NAMES.has(eventName)) {\n throw new Error(`Unsupported BluetoothSdk event \"${eventName}\". Use @mentra/bluetooth-sdk/react for status state.`)\n }\n return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)\n}\n\nconst startOtaUpdate: BluetoothSdkPublicModule[\"startOtaUpdate\"] = () => {\n return PrivateBluetoothSdkModule.startOtaUpdate()\n}\n\nconst bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]\n if (typeof method === \"function\") {\n return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]\n }\n\n return (async () => {\n throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)\n }) as unknown as BluetoothSdkPublicModule[K]\n}\n\nexport const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({\n addListener,\n getDefaultDevice: bindPublicMethod(\"getDefaultDevice\"),\n setDefaultDevice: bindPublicMethod(\"setDefaultDevice\"),\n clearDefaultDevice: bindPublicMethod(\"clearDefaultDevice\"),\n startScan: bindPublicMethod(\"startScan\"),\n stopScan: bindPublicMethod(\"stopScan\"),\n scan: bindPublicMethod(\"scan\") as BluetoothSdkPublicModule[\"scan\"],\n connect: bindPublicMethod(\"connect\"),\n connectDefault: bindPublicMethod(\"connectDefault\"),\n cancelConnectionAttempt: bindPublicMethod(\"cancelConnectionAttempt\"),\n disconnect: bindPublicMethod(\"disconnect\"),\n forget: bindPublicMethod(\"forget\"),\n displayText: bindPublicMethod(\"displayText\"),\n clearDisplay: bindPublicMethod(\"clearDisplay\"),\n showDashboard: bindPublicMethod(\"showDashboard\"),\n setDashboardPosition: bindPublicMethod(\"setDashboardPosition\"),\n setHeadUpAngle: bindPublicMethod(\"setHeadUpAngle\"),\n setImuEnabled: bindPublicMethod(\"setImuEnabled\"),\n setScreenDisabled: bindPublicMethod(\"setScreenDisabled\"),\n requestWifiScan: bindPublicMethod(\"requestWifiScan\"),\n sendWifiCredentials: bindPublicMethod(\"sendWifiCredentials\"),\n forgetWifiNetwork: bindPublicMethod(\"forgetWifiNetwork\"),\n setHotspotState: bindPublicMethod(\"setHotspotState\"),\n setGalleryModeEnabled: bindPublicMethod(\"setGalleryModeEnabled\"),\n setVoiceActivityDetectionEnabled: bindPublicMethod(\"setVoiceActivityDetectionEnabled\"),\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for AE ÷3, or explicit per-shot\n * fields). Still functional until removed in a future release.\n */\n setPhotoCaptureDefaults: bindPublicMethod(\"setPhotoCaptureDefaults\"),\n setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults\n if (typeof method !== \"function\") {\n return Promise.reject(\n new Error(\"BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app.\"),\n )\n }\n return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)\n },\n setMaxVideoRecordingDuration: bindPublicMethod(\"setMaxVideoRecordingDuration\"),\n setCameraFov: bindPublicMethod(\"setCameraFov\"),\n setCameraTuningConfig: bindPublicMethod(\"setCameraTuningConfig\"),\n queryGalleryStatus: bindPublicMethod(\"queryGalleryStatus\"),\n requestPhoto: bindPublicMethod(\"requestPhoto\"),\n warmUpCamera: bindPublicMethod(\"warmUpCamera\"),\n startVideoRecording: bindPublicMethod(\"startVideoRecording\"),\n stopVideoRecording: bindPublicMethod(\"stopVideoRecording\"),\n startStream: bindPublicMethod(\"startStream\"),\n stopStream: bindPublicMethod(\"stopStream\"),\n setMicState: bindPublicMethod(\"setMicState\"),\n setPreferredMic: bindPublicMethod(\"setPreferredMic\"),\n setOwnAppAudioPlaying: bindPublicMethod(\"setOwnAppAudioPlaying\"),\n getGlassesMediaVolume: bindPublicMethod(\"getGlassesMediaVolume\"),\n setGlassesMediaVolume: bindPublicMethod(\"setGlassesMediaVolume\"),\n rgbLedControl: bindPublicMethod(\"rgbLedControl\"),\n requestVersionInfo: bindPublicMethod(\"requestVersionInfo\"),\n checkForOtaUpdate: bindPublicMethod(\"checkForOtaUpdate\"),\n startOtaUpdate,\n setSttModelDetails: bindPublicMethod(\"setSttModelDetails\"),\n getSttModelPath: bindPublicMethod(\"getSttModelPath\"),\n checkSttModelAvailable: bindPublicMethod(\"checkSttModelAvailable\"),\n validateSttModel: bindPublicMethod(\"validateSttModel\"),\n extractTarBz2: bindPublicMethod(\"extractTarBz2\"),\n restartTranscriber: bindPublicMethod(\"restartTranscriber\"),\n setTtsModelDetails: bindPublicMethod(\"setTtsModelDetails\"),\n getTtsModelPath: bindPublicMethod(\"getTtsModelPath\"),\n getTtsModelLanguage: bindPublicMethod(\"getTtsModelLanguage\"),\n checkTtsModelAvailable: bindPublicMethod(\"checkTtsModelAvailable\"),\n validateTtsModel: bindPublicMethod(\"validateTtsModel\"),\n generateTtsAudio: bindPublicMethod(\"generateTtsAudio\"),\n})\n\nexport default BluetoothSdk\n\nexport {\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n DeviceModels,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AccelEvent,\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n PhotoCaptureDefaults,\n ButtonPressEvent,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovResult,\n CameraRoiPosition,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicMode,\n MicPcmEvent,\n MicPreference,\n OtaStartAckEvent,\n OtaStatus,\n OtaStatusEvent,\n OtaQueryResult,\n PairFailureEvent,\n PhotoCaptureMetadata,\n PhotoResolvedConfig,\n PhotoCompression,\n PhotoFpsRange,\n PhotoMeteredPreview,\n PhotoMode,\n PhotoResponseEvent,\n PhotoRequestedCaptureConfig,\n PhotoRequestParams,\n PhotoSize,\n PhotoStatusEvent,\n PhotoStatusState,\n PhotoSuccessResponseEvent,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n RgbLedControlSuccessResponseEvent,\n ScanModelOptions,\n ScanOptions,\n ScanResultsCallback,\n SpeakingStatusEvent,\n SettingsAckEvent,\n SettingsAckSetting,\n SettingsAckSuccessEvent,\n SettingsAckSuccessStatus,\n SettingsAckStatus,\n StreamAudioConfig,\n StreamResolvedConfig,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VideoRecordingDefaults,\n VideoRecordingStartedStatusEvent,\n VideoRecordingStatusEvent,\n VideoRecordingStatusState,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingSuccessStatusEvent,\n VersionInfoEvent,\n VersionInfoResult,\n WifiScanResultEvent,\n VoiceActivityDetectionStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import PrivateBluetoothSdkModule from \"./_private/BluetoothSdkModule\"\nimport type {\n BluetoothSdkEventListener,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule,\n VideoRecordingDefaults,\n} from \"./BluetoothSdk.types\"\n\nconst PUBLIC_EVENT_NAMES = new Set<BluetoothSdkEventName>([\n \"log\",\n \"device_discovered\",\n \"default_device_changed\",\n \"glasses_not_ready\",\n \"button_press\",\n \"touch_event\",\n \"accel_event\",\n \"head_up\",\n \"voice_activity_detection_status\",\n \"speaking_status\",\n \"battery_status\",\n \"local_transcription\",\n \"wifi_status_change\",\n \"wifi_scan_result\",\n \"hotspot_status_change\",\n \"hotspot_error\",\n \"photo_response\",\n \"photo_status\",\n \"camera_status\",\n \"video_recording_status\",\n \"media_success\",\n \"media_error\",\n \"gallery_status\",\n \"compatible_glasses_search_stop\",\n \"swipe_volume_status\",\n \"switch_status\",\n \"rgb_led_control_response\",\n \"settings_ack\",\n \"pair_failure\",\n \"audio_pairing_needed\",\n \"audio_connected\",\n \"audio_disconnected\",\n \"mic_pcm\",\n \"mic_lc3\",\n \"stream_status\",\n \"ota_start_ack\",\n \"ota_status\",\n \"ar99_ota_status\",\n \"version_info\",\n \"extraction_progress\",\n])\n\nconst addListener: BluetoothSdkPublicModule[\"addListener\"] = (eventName, listener) => {\n if (!PUBLIC_EVENT_NAMES.has(eventName)) {\n throw new Error(`Unsupported BluetoothSdk event \"${eventName}\". Use @mentra/bluetooth-sdk/react for status state.`)\n }\n return PrivateBluetoothSdkModule.addListener(eventName, listener as BluetoothSdkEventListener<BluetoothSdkEventName>)\n}\n\nconst startOtaUpdate: BluetoothSdkPublicModule[\"startOtaUpdate\"] = () => {\n return PrivateBluetoothSdkModule.startOtaUpdate()\n}\n\nconst bindPublicMethod = <K extends keyof BluetoothSdkPublicModule>(name: K): BluetoothSdkPublicModule[K] => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>)[name]\n if (typeof method === \"function\") {\n return method.bind(PrivateBluetoothSdkModule) as BluetoothSdkPublicModule[K]\n }\n\n return (async () => {\n throw new Error(`BluetoothSdk.${String(name)} is not available in this native build. Rebuild the app.`)\n }) as unknown as BluetoothSdkPublicModule[K]\n}\n\nexport const BluetoothSdk: BluetoothSdkPublicModule = Object.freeze({\n addListener,\n getDefaultDevice: bindPublicMethod(\"getDefaultDevice\"),\n setDefaultDevice: bindPublicMethod(\"setDefaultDevice\"),\n clearDefaultDevice: bindPublicMethod(\"clearDefaultDevice\"),\n startScan: bindPublicMethod(\"startScan\"),\n stopScan: bindPublicMethod(\"stopScan\"),\n scan: bindPublicMethod(\"scan\") as BluetoothSdkPublicModule[\"scan\"],\n connect: bindPublicMethod(\"connect\"),\n connectDefault: bindPublicMethod(\"connectDefault\"),\n cancelConnectionAttempt: bindPublicMethod(\"cancelConnectionAttempt\"),\n disconnect: bindPublicMethod(\"disconnect\"),\n forget: bindPublicMethod(\"forget\"),\n displayText: bindPublicMethod(\"displayText\"),\n clearDisplay: bindPublicMethod(\"clearDisplay\"),\n showDashboard: bindPublicMethod(\"showDashboard\"),\n setDashboardPosition: bindPublicMethod(\"setDashboardPosition\"),\n setHeadUpAngle: bindPublicMethod(\"setHeadUpAngle\"),\n setImuEnabled: bindPublicMethod(\"setImuEnabled\"),\n setScreenDisabled: bindPublicMethod(\"setScreenDisabled\"),\n requestWifiScan: bindPublicMethod(\"requestWifiScan\"),\n sendWifiCredentials: bindPublicMethod(\"sendWifiCredentials\"),\n forgetWifiNetwork: bindPublicMethod(\"forgetWifiNetwork\"),\n setHotspotState: bindPublicMethod(\"setHotspotState\"),\n setGalleryModeEnabled: bindPublicMethod(\"setGalleryModeEnabled\"),\n setVoiceActivityDetectionEnabled: bindPublicMethod(\"setVoiceActivityDetectionEnabled\"),\n setLoudnessGateEnabled: bindPublicMethod(\"setLoudnessGateEnabled\"),\n /**\n * @deprecated Sticky action-button photo presets are deprecated. Prefer per-request\n * `requestPhoto(...)` options (e.g. `mode: \"text\"` for text sensor size/crop, or explicit per-shot\n * fields). Still functional until removed in a future release.\n */\n setPhotoCaptureDefaults: bindPublicMethod(\"setPhotoCaptureDefaults\"),\n setVideoRecordingDefaults: ({width, height, fps}: VideoRecordingDefaults) => {\n const method = (PrivateBluetoothSdkModule as unknown as Record<string, unknown>).setVideoRecordingDefaults\n if (typeof method !== \"function\") {\n return Promise.reject(\n new Error(\"BluetoothSdk.setVideoRecordingDefaults is not available in this native build. Rebuild the app.\"),\n )\n }\n return PrivateBluetoothSdkModule.setVideoRecordingDefaults(width, height, fps)\n },\n setMaxVideoRecordingDuration: bindPublicMethod(\"setMaxVideoRecordingDuration\"),\n setCameraFov: bindPublicMethod(\"setCameraFov\"),\n setLegacyCameraFov: bindPublicMethod(\"setLegacyCameraFov\"),\n setCameraFovOverride: bindPublicMethod(\"setCameraFovOverride\"),\n releaseCameraFovOverride: bindPublicMethod(\"releaseCameraFovOverride\"),\n setCameraTuningConfig: bindPublicMethod(\"setCameraTuningConfig\"),\n queryGalleryStatus: bindPublicMethod(\"queryGalleryStatus\"),\n requestPhoto: bindPublicMethod(\"requestPhoto\"),\n warmUpCamera: bindPublicMethod(\"warmUpCamera\"),\n stopCameraWarmUp: bindPublicMethod(\"stopCameraWarmUp\"),\n startVideoRecording: bindPublicMethod(\"startVideoRecording\"),\n stopVideoRecording: bindPublicMethod(\"stopVideoRecording\"),\n startStream: bindPublicMethod(\"startStream\"),\n stopStream: bindPublicMethod(\"stopStream\"),\n setMicState: bindPublicMethod(\"setMicState\"),\n setPreferredMic: bindPublicMethod(\"setPreferredMic\"),\n setOwnAppAudioPlaying: bindPublicMethod(\"setOwnAppAudioPlaying\"),\n getGlassesMediaVolume: bindPublicMethod(\"getGlassesMediaVolume\"),\n setGlassesMediaVolume: bindPublicMethod(\"setGlassesMediaVolume\"),\n rgbLedControl: bindPublicMethod(\"rgbLedControl\"),\n requestVersionInfo: bindPublicMethod(\"requestVersionInfo\"),\n checkForOtaUpdate: bindPublicMethod(\"checkForOtaUpdate\"),\n startOtaUpdate,\n startAr99OtaFromFile: bindPublicMethod(\"startAr99OtaFromFile\"),\n cancelAr99Ota: bindPublicMethod(\"cancelAr99Ota\"),\n sendAr99FactoryReset: bindPublicMethod(\"sendAr99FactoryReset\"),\n buildAr99OtaSignature: bindPublicMethod(\"buildAr99OtaSignature\"),\n setSttModelDetails: bindPublicMethod(\"setSttModelDetails\"),\n getSttModelPath: bindPublicMethod(\"getSttModelPath\"),\n checkSttModelAvailable: bindPublicMethod(\"checkSttModelAvailable\"),\n validateSttModel: bindPublicMethod(\"validateSttModel\"),\n extractTarBz2: bindPublicMethod(\"extractTarBz2\"),\n restartTranscriber: bindPublicMethod(\"restartTranscriber\"),\n setTtsModelDetails: bindPublicMethod(\"setTtsModelDetails\"),\n getTtsModelPath: bindPublicMethod(\"getTtsModelPath\"),\n getTtsModelLanguage: bindPublicMethod(\"getTtsModelLanguage\"),\n checkTtsModelAvailable: bindPublicMethod(\"checkTtsModelAvailable\"),\n validateTtsModel: bindPublicMethod(\"validateTtsModel\"),\n generateTtsAudio: bindPublicMethod(\"generateTtsAudio\"),\n})\n\nexport default BluetoothSdk\n\nexport {\n CAMERA_FOV_DEFAULT,\n CAMERA_FOV_MAX,\n CAMERA_FOV_MIN,\n DeviceModels,\n isBusyGlassesConnectionStatus,\n isConnectedGlassesConnectionStatus,\n isConnectedWifiStatus,\n isEnabledHotspotStatus,\n isReadyGlassesConnectionStatus,\n} from \"./BluetoothSdk.types\"\n\nexport type {\n AccelEvent,\n Ar99OtaStatusEvent,\n AudioConnectedEvent,\n AudioDisconnectedEvent,\n AudioPairingNeededEvent,\n BatteryStatusEvent,\n BluetoothSdkEvent,\n BluetoothSdkEventListener,\n BluetoothSdkEventMap,\n BluetoothSdkEventName,\n BluetoothSdkPublicModule as BluetoothSdkModule,\n BluetoothSdkSubscription,\n ButtonPhotoSize,\n PhotoCaptureDefaults,\n ButtonPressEvent,\n CameraFovPreset,\n CameraFovRequest,\n CameraFovResult,\n CameraRoiPosition,\n CompatibleGlassesSearchStopEvent,\n ConnectOptions,\n ConnectedGlassesConnectionStatus,\n ConnectedWifiStatus,\n Device,\n DeviceModel,\n EnabledHotspotStatus,\n GalleryStatusEvent,\n GlassesConnectionStatus,\n GlassesMediaVolumeGetResult,\n GlassesMediaVolumeSetResult,\n GlassesNotReadyEvent,\n HeadUpEvent,\n HotspotErrorEvent,\n HotspotStatus,\n HotspotStatusChangeEvent,\n LocalTranscriptionEvent,\n LogEvent,\n MicLc3Event,\n MicMode,\n MicPcmEvent,\n MicPreference,\n OtaStartAckEvent,\n OtaStatus,\n OtaStatusEvent,\n OtaQueryResult,\n PairFailureEvent,\n PhotoCaptureMetadata,\n PhotoResolvedConfig,\n PhotoCompression,\n PhotoFpsRange,\n PhotoMeteredPreview,\n PhotoMode,\n PhotoTransferMethod,\n PhotoResponseEvent,\n PhotoRequestedCaptureConfig,\n PhotoRequestParams,\n PhotoSize,\n PhotoStatusEvent,\n PhotoStatusState,\n PhotoSuccessResponseEvent,\n RgbLedAction,\n RgbLedColor,\n RgbLedControlResponseEvent,\n RgbLedControlSuccessResponseEvent,\n ScanModelOptions,\n ScanOptions,\n ScanResultsCallback,\n SpeakingStatusEvent,\n SettingsAckEvent,\n SettingsAckSetting,\n SettingsAckSuccessEvent,\n SettingsAckSuccessStatus,\n SettingsAckStatus,\n StreamAudioConfig,\n StreamResolvedConfig,\n StreamStartRequest,\n StreamStatusEvent,\n StreamStatusLifecycleState,\n StreamStatusReconnectState,\n StreamStatusState,\n StreamVideoConfig,\n SwipeVolumeStatusEvent,\n SwitchStatusEvent,\n TouchEvent,\n VideoRecordingDefaults,\n VideoRecordingStartedStatusEvent,\n VideoRecordingStatusEvent,\n VideoRecordingStatusState,\n VideoRecordingStoppedStatusEvent,\n VideoRecordingSuccessStatusEvent,\n VersionInfoEvent,\n VersionInfoResult,\n WifiScanResultEvent,\n VoiceActivityDetectionStatusEvent,\n WifiSearchResult,\n WifiStatus,\n WifiStatusChangeEvent,\n} from \"./BluetoothSdk.types\"\n"]}
@@ -6,6 +6,7 @@
6
6
  "android": {
7
7
  "modules": [
8
8
  "com.mentra.bluetoothsdk.BluetoothSdkModule",
9
+ "com.mentra.bluetoothsdk.MentraLocalNetworkModule",
9
10
  "com.mentra.bluetoothsdk.photoreceiver.MentraPhotoReceiverModule"
10
11
  ]
11
12
  }
@@ -1,3 +1,4 @@
1
+ import CryptoKit
1
2
  import ExpoModulesCore
2
3
  import Foundation
3
4
 
@@ -59,9 +60,11 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
59
60
  "stream_status",
60
61
  "keep_alive_ack",
61
62
  "mtk_update_complete",
63
+ "glasses_session_changed",
62
64
  "ota_progress",
63
65
  "ota_start_ack",
64
66
  "ota_status",
67
+ "ar99_ota_status",
65
68
  "send_command_to_ble",
66
69
  "receive_command_from_ble",
67
70
  "miniapp_selected",
@@ -77,6 +80,9 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
77
80
  }
78
81
 
79
82
  OnDestroy {
83
+ Task {
84
+ await PcmStreamManager.abortAll()
85
+ }
80
86
  Task { @MainActor [weak self] in
81
87
  self?.sdk?.invalidate()
82
88
  self?.sdk = nil
@@ -326,6 +332,11 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
326
332
  try await sdk.setVoiceActivityDetectionEnabled(enabled)
327
333
  }
328
334
 
335
+ AsyncFunction("setLoudnessGateEnabled") { (enabled: Bool) in
336
+ let sdk = await MainActor.run { self.bluetoothSdk() }
337
+ try await sdk.setLoudnessGateEnabled(enabled)
338
+ }
339
+
329
340
  AsyncFunction("setPhotoCaptureDefaults") { (params: [String: Any]) in
330
341
  let sdk = await MainActor.run { self.bluetoothSdk() }
331
342
  return try await sdk.setPhotoCaptureDefaults(PhotoCaptureDefaults.from(params: params)).values
@@ -350,6 +361,42 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
350
361
  return try await sdk.setCameraFov(CameraFov(fov: value, roiPosition: roiPosition)).values
351
362
  }
352
363
 
364
+ AsyncFunction("setLegacyCameraFov") { (fov: [String: Any]) in
365
+ let value = intValue(fov["fov"]) ?? CameraFov.defaultFov
366
+ let roiPosition = CameraRoiPosition.from(
367
+ rawValue: intValue(fov["roiPosition"]) ?? intValue(fov["roi_position"])
368
+ )
369
+ let sdk = await MainActor.run { self.bluetoothSdk() }
370
+ return try sdk.setLegacyCameraFov(CameraFov(fov: value, roiPosition: roiPosition)).values
371
+ }
372
+
373
+ AsyncFunction("restoreLegacyCameraFov") {
374
+ let sdk = await MainActor.run { self.bluetoothSdk() }
375
+ try sdk.restoreLegacyCameraFov()
376
+ }
377
+
378
+ AsyncFunction("setCameraFovOverride") { (params: [String: Any]) in
379
+ guard let leaseId = params["leaseId"] as? String, !leaseId.isEmpty else {
380
+ throw BluetoothSdkError(code: "invalid_request", message: "leaseId is required")
381
+ }
382
+ let value = intValue(params["fov"]) ?? CameraFov.defaultFov
383
+ let roiPosition = CameraRoiPosition.from(
384
+ rawValue: intValue(params["roiPosition"]) ?? intValue(params["roi_position"])
385
+ )
386
+ let ttlMs = intValue(params["ttlMs"]) ?? 300_000
387
+ let sdk = await MainActor.run { self.bluetoothSdk() }
388
+ return try await sdk.setCameraFovOverride(
389
+ leaseId: leaseId,
390
+ fov: CameraFov(fov: value, roiPosition: roiPosition),
391
+ ttlMs: ttlMs
392
+ ).values
393
+ }
394
+
395
+ AsyncFunction("releaseCameraFovOverride") { (leaseId: String) in
396
+ let sdk = await MainActor.run { self.bluetoothSdk() }
397
+ return try await sdk.releaseCameraFovOverride(leaseId: leaseId).values
398
+ }
399
+
353
400
  AsyncFunction("setCameraTuningConfig") { (anrOn: Bool, gainOn: Bool) in
354
401
  let sdk = await MainActor.run { self.bluetoothSdk() }
355
402
  return try await sdk.setCameraTuningConfig(anrOn: anrOn, gainOn: gainOn).values
@@ -361,7 +408,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
361
408
  }
362
409
 
363
410
  AsyncFunction("requestPhoto") { (params: [String: Any]) in
364
- let req = PhotoRequest.from(params: params)
411
+ let req = try PhotoRequest.from(params: params)
365
412
  Bridge.log(
366
413
  "NATIVE: PHOTO PIPELINE [3/6] BluetoothSdk.requestPhoto requestId=\(req.requestId) size=\(req.size.rawValue) compress=\(req.compress?.rawValue ?? "none") aeDivisor=\(req.aeExposureDivisor.map { String($0) } ?? "nil")"
367
414
  )
@@ -374,6 +421,7 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
374
421
  let requestId = params["requestId"] as? String
375
422
  let sizeRaw = params["size"] as? String ?? "medium"
376
423
  let size = PhotoSize(normalizedRawValue: sizeRaw)
424
+ let mode = PhotoMode(normalizedRawValue: params["mode"] as? String)
377
425
  let exposureTimeNs: Double?
378
426
  switch params["exposureTimeNs"] {
379
427
  case let value as Double:
@@ -388,16 +436,26 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
388
436
  }
389
437
  let durationRaw = intValue(params["durationMs"]) ?? 0
390
438
  let durationMs = durationRaw > 0 ? durationRaw : 15000
439
+ let zsl = params["zsl"] as? Bool
440
+ let mfnr = params["mfnr"] as? Bool
391
441
 
392
442
  let sdk = await MainActor.run { self.bluetoothSdk() }
393
443
  return try await sdk.warmUpCamera(
394
444
  requestId: requestId,
395
445
  size: size,
446
+ mode: mode,
396
447
  exposureTimeNs: exposureTimeNs,
397
- durationMs: durationMs
448
+ durationMs: durationMs,
449
+ zsl: zsl,
450
+ mfnr: mfnr
398
451
  ).values
399
452
  }
400
453
 
454
+ AsyncFunction("stopCameraWarmUp") { (requestId: String) in
455
+ let sdk = await MainActor.run { self.bluetoothSdk() }
456
+ try sdk.stopCameraWarmUp(requestId: requestId)
457
+ }
458
+
401
459
  // MARK: - OTA Commands
402
460
 
403
461
  Function("setOtaVersionUrl") { (otaVersionUrl: String) in
@@ -432,6 +490,27 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
432
490
  return try await sdk.sendOtaQueryStatus().values
433
491
  }
434
492
 
493
+ AsyncFunction("startAr99OtaFromFile") { (path: String) in
494
+ let sdk = await MainActor.run { self.bluetoothSdk() }
495
+ return try await MainActor.run { try sdk.startAr99OtaFromFile(path) }
496
+ }
497
+
498
+ AsyncFunction("cancelAr99Ota") {
499
+ let sdk = await MainActor.run { self.bluetoothSdk() }
500
+ await MainActor.run { sdk.cancelAr99Ota() }
501
+ }
502
+
503
+ AsyncFunction("sendAr99FactoryReset") {
504
+ let sdk = await MainActor.run { self.bluetoothSdk() }
505
+ try await MainActor.run { try sdk.sendAr99FactoryReset() }
506
+ }
507
+
508
+
509
+ Function("buildAr99OtaSignature") { (secret: String, appName: String, currentVersion: String, serialNumber: String, nonce: String) in
510
+ let raw = secret + appName + "juxinOTA" + currentVersion + serialNumber.trimmingCharacters(in: .whitespacesAndNewlines) + nonce
511
+ let digest = Insecure.MD5.hash(data: Data(raw.utf8))
512
+ return digest.map { String(format: "%02x", $0) }.joined()
513
+ }
435
514
  // MARK: - Version Info Commands
436
515
 
437
516
  AsyncFunction("requestVersionInfo") {
@@ -514,6 +593,32 @@ public class BluetoothSdkModule: Module, MentraBluetoothSDKDelegate {
514
593
  }
515
594
  }
516
595
 
596
+ // MARK: - Live PCM output stream (miniapp speaker.createStream)
597
+
598
+ AsyncFunction("pcmStreamOpen") {
599
+ (streamId: String, sampleRate: Int, channels: Int, volume: Double) async throws in
600
+ try PcmStreamManager.open(
601
+ streamId: streamId,
602
+ sampleRate: sampleRate,
603
+ channels: channels,
604
+ volume: Float(volume)
605
+ )
606
+ }
607
+
608
+ AsyncFunction("pcmStreamWrite") {
609
+ (streamId: String, base64: String) async throws -> [String: Int64] in
610
+ try ["bufferedMs": await PcmStreamManager.write(streamId: streamId, base64: base64)]
611
+ }
612
+
613
+ AsyncFunction("pcmStreamClose") {
614
+ (streamId: String) async throws -> [String: Int64] in
615
+ try ["durationMs": await PcmStreamManager.close(streamId: streamId)]
616
+ }
617
+
618
+ AsyncFunction("pcmStreamAbort") { (streamId: String) async in
619
+ await PcmStreamManager.abort(streamId: streamId)
620
+ }
621
+
517
622
  AsyncFunction("getGlassesMediaVolume") { () async throws -> [String: Any] in
518
623
  try await DeviceManager.shared.getGlassesMediaVolume()
519
624
  }
@@ -812,3 +917,9 @@ private extension ConnectOptions {
812
917
  )
813
918
  }
814
919
  }
920
+
921
+
922
+
923
+
924
+
925
+
@@ -7,7 +7,8 @@ enum BluetoothSdkDefaults {
7
7
  }
8
8
 
9
9
  static let voiceActivityDetectionEnabled = false
10
- private static let swiftPackageSdkVersion = "0.1.20"
10
+ static let loudnessGateEnabled = true
11
+ private static let swiftPackageSdkVersion = "0.1.21-beta.1"
11
12
  private static let swiftPackageSdkVersionPlaceholder = "__MENTRA" + "_BLUETOOTH_SDK_VERSION__"
12
13
 
13
14
  private static func normalizedSdkVersion(_ value: String?) -> String? {