@mentra/engine 0.1.0-dev.0 → 3.1.0-dev.10

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 (503) hide show
  1. package/README.md +55 -18
  2. package/build/bluetooth-sdk/debug.d.ts +2 -0
  3. package/build/bluetooth-sdk/debug.d.ts.map +1 -0
  4. package/build/bluetooth-sdk/debug.js +2 -0
  5. package/build/bluetooth-sdk/debug.js.map +1 -0
  6. package/build/bluetooth-sdk/index.d.ts +3 -0
  7. package/build/bluetooth-sdk/index.d.ts.map +1 -0
  8. package/build/bluetooth-sdk/index.js +3 -0
  9. package/build/bluetooth-sdk/index.js.map +1 -0
  10. package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
  11. package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
  12. package/build/bluetooth-sdk/photo-receiver.js +3 -0
  13. package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
  14. package/build/bluetooth-sdk/react.d.ts +2 -0
  15. package/build/bluetooth-sdk/react.d.ts.map +1 -0
  16. package/build/bluetooth-sdk/react.js +2 -0
  17. package/build/bluetooth-sdk/react.js.map +1 -0
  18. package/build/bluetooth-sdk/types.d.ts +2 -0
  19. package/build/bluetooth-sdk/types.d.ts.map +1 -0
  20. package/build/bluetooth-sdk/types.js +2 -0
  21. package/build/bluetooth-sdk/types.js.map +1 -0
  22. package/build/engine.d.ts +24 -16
  23. package/build/engine.d.ts.map +1 -1
  24. package/build/engine.js +9 -4
  25. package/build/engine.js.map +1 -1
  26. package/build/facades/dev.d.ts +3 -2
  27. package/build/facades/dev.d.ts.map +1 -1
  28. package/build/facades/dev.js +18 -12
  29. package/build/facades/dev.js.map +1 -1
  30. package/build/facades/display.d.ts +1 -1
  31. package/build/facades/display.d.ts.map +1 -1
  32. package/build/facades/display.js +1 -1
  33. package/build/facades/display.js.map +1 -1
  34. package/build/facades/gallery.js +1 -1
  35. package/build/facades/gallery.js.map +1 -1
  36. package/build/facades/glasses.d.ts +4 -13
  37. package/build/facades/glasses.d.ts.map +1 -1
  38. package/build/facades/glasses.js +21 -6
  39. package/build/facades/glasses.js.map +1 -1
  40. package/build/facades/glassesSettings.d.ts.map +1 -1
  41. package/build/facades/glassesSettings.js +1 -0
  42. package/build/facades/glassesSettings.js.map +1 -1
  43. package/build/facades/miniapps.d.ts +4 -0
  44. package/build/facades/miniapps.d.ts.map +1 -1
  45. package/build/facades/miniapps.js +5 -0
  46. package/build/facades/miniapps.js.map +1 -1
  47. package/build/facades/ota.d.ts +14 -16
  48. package/build/facades/ota.d.ts.map +1 -1
  49. package/build/facades/ota.js +22 -7
  50. package/build/facades/ota.js.map +1 -1
  51. package/build/facades/pairing.d.ts +8 -5
  52. package/build/facades/pairing.d.ts.map +1 -1
  53. package/build/facades/pairing.js +12 -10
  54. package/build/facades/pairing.js.map +1 -1
  55. package/build/facades/permissions.d.ts +10 -0
  56. package/build/facades/permissions.d.ts.map +1 -1
  57. package/build/facades/permissions.js +10 -0
  58. package/build/facades/permissions.js.map +1 -1
  59. package/build/facades/phoneNotifications.d.ts +0 -4
  60. package/build/facades/phoneNotifications.d.ts.map +1 -1
  61. package/build/facades/phoneNotifications.js +4 -14
  62. package/build/facades/phoneNotifications.js.map +1 -1
  63. package/build/facades/speech.d.ts +7 -6
  64. package/build/facades/speech.d.ts.map +1 -1
  65. package/build/facades/speech.js +1 -1
  66. package/build/facades/speech.js.map +1 -1
  67. package/build/generated/releaseMetadata.d.ts +12 -0
  68. package/build/generated/releaseMetadata.d.ts.map +1 -0
  69. package/build/generated/releaseMetadata.js +10 -0
  70. package/build/generated/releaseMetadata.js.map +1 -0
  71. package/build/index.d.ts +10 -8
  72. package/build/index.d.ts.map +1 -1
  73. package/build/index.js +6 -5
  74. package/build/index.js.map +1 -1
  75. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  76. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  77. package/build/react/MentraLiveOtaFlow.js +528 -0
  78. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  79. package/build/react/index.d.ts +2 -0
  80. package/build/react/index.d.ts.map +1 -0
  81. package/build/react/index.js +2 -0
  82. package/build/react/index.js.map +1 -0
  83. package/build/react/useEngineSnapshot.d.ts +2 -0
  84. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  85. package/build/react/useEngineSnapshot.js +14 -0
  86. package/build/react/useEngineSnapshot.js.map +1 -0
  87. package/build/runtime/bootstrap.d.ts +24 -1
  88. package/build/runtime/bootstrap.d.ts.map +1 -1
  89. package/build/runtime/bootstrap.js +17 -0
  90. package/build/runtime/bootstrap.js.map +1 -1
  91. package/build/runtime/scanQrSeam.d.ts +7 -0
  92. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  93. package/build/runtime/scanQrSeam.js +16 -0
  94. package/build/runtime/scanQrSeam.js.map +1 -0
  95. package/build/services/AppRegistry.d.ts +41 -57
  96. package/build/services/AppRegistry.d.ts.map +1 -1
  97. package/build/services/AppRegistry.js +208 -144
  98. package/build/services/AppRegistry.js.map +1 -1
  99. package/build/services/AudioCloudUplink.d.ts +12 -0
  100. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  101. package/build/services/AudioCloudUplink.js +22 -1
  102. package/build/services/AudioCloudUplink.js.map +1 -1
  103. package/build/services/AudioPlaybackService.d.ts +41 -2
  104. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  105. package/build/services/AudioPlaybackService.js +250 -33
  106. package/build/services/AudioPlaybackService.js.map +1 -1
  107. package/build/services/BlobStore.d.ts +2 -1
  108. package/build/services/BlobStore.d.ts.map +1 -1
  109. package/build/services/BlobStore.js +17 -9
  110. package/build/services/BlobStore.js.map +1 -1
  111. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  112. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  113. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  114. package/build/services/CloudClientService.d.ts +15 -0
  115. package/build/services/CloudClientService.d.ts.map +1 -1
  116. package/build/services/CloudClientService.js +93 -1
  117. package/build/services/CloudClientService.js.map +1 -1
  118. package/build/services/DeviceEventRouter.js +5 -5
  119. package/build/services/DeviceEventRouter.js.map +1 -1
  120. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  121. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  122. package/build/services/ForegroundLocationPermission.js +12 -0
  123. package/build/services/ForegroundLocationPermission.js.map +1 -0
  124. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  125. package/build/services/GlassesSettingsSync.js +9 -3
  126. package/build/services/GlassesSettingsSync.js.map +1 -1
  127. package/build/services/GlassesStatusProjection.d.ts +2 -1
  128. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  129. package/build/services/GlassesStatusProjection.js +15 -8
  130. package/build/services/GlassesStatusProjection.js.map +1 -1
  131. package/build/services/HotspotOtaTransport.d.ts +29 -0
  132. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  133. package/build/services/HotspotOtaTransport.js +146 -0
  134. package/build/services/HotspotOtaTransport.js.map +1 -0
  135. package/build/services/HotspotShutdown.d.ts +17 -0
  136. package/build/services/HotspotShutdown.d.ts.map +1 -0
  137. package/build/services/HotspotShutdown.js +29 -0
  138. package/build/services/HotspotShutdown.js.map +1 -0
  139. package/build/services/LocalDisplayManager.d.ts +15 -0
  140. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  141. package/build/services/LocalDisplayManager.js +106 -20
  142. package/build/services/LocalDisplayManager.js.map +1 -1
  143. package/build/services/LocalMiniappRuntime.d.ts +74 -2
  144. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  145. package/build/services/LocalMiniappRuntime.js +785 -291
  146. package/build/services/LocalMiniappRuntime.js.map +1 -1
  147. package/build/services/LocalMiniappStorage.d.ts +32 -0
  148. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  149. package/build/services/LocalMiniappStorage.js +66 -0
  150. package/build/services/LocalMiniappStorage.js.map +1 -0
  151. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  152. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  153. package/build/services/LocalMiniappUserIdentity.js +43 -0
  154. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  155. package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
  156. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  157. package/build/services/LocalSttFallbackCoordinator.js +18 -12
  158. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  159. package/build/services/MicStateCoordinator.d.ts +42 -1
  160. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  161. package/build/services/MicStateCoordinator.js +141 -3
  162. package/build/services/MicStateCoordinator.js.map +1 -1
  163. package/build/services/MiniappLauncher.d.ts.map +1 -1
  164. package/build/services/MiniappLauncher.js +23 -3
  165. package/build/services/MiniappLauncher.js.map +1 -1
  166. package/build/services/MiniappLiveness.d.ts +12 -0
  167. package/build/services/MiniappLiveness.d.ts.map +1 -0
  168. package/build/services/MiniappLiveness.js +16 -0
  169. package/build/services/MiniappLiveness.js.map +1 -0
  170. package/build/services/NativeHttpResponse.d.ts +3 -0
  171. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  172. package/build/services/NativeHttpResponse.js +6 -0
  173. package/build/services/NativeHttpResponse.js.map +1 -0
  174. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  175. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  176. package/build/services/OtaArtifactDownloader.js +226 -0
  177. package/build/services/OtaArtifactDownloader.js.map +1 -0
  178. package/build/services/OtaAutoChain.d.ts +34 -0
  179. package/build/services/OtaAutoChain.d.ts.map +1 -0
  180. package/build/services/OtaAutoChain.js +83 -0
  181. package/build/services/OtaAutoChain.js.map +1 -0
  182. package/build/services/OtaErrorMapping.d.ts +18 -0
  183. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  184. package/build/services/OtaErrorMapping.js +63 -0
  185. package/build/services/OtaErrorMapping.js.map +1 -0
  186. package/build/services/OtaInstallCoordinator.d.ts +95 -15
  187. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  188. package/build/services/OtaInstallCoordinator.js +577 -130
  189. package/build/services/OtaInstallCoordinator.js.map +1 -1
  190. package/build/services/OtaService.d.ts.map +1 -1
  191. package/build/services/OtaService.js +8 -1
  192. package/build/services/OtaService.js.map +1 -1
  193. package/build/services/OtaUpdateCheckService.d.ts +39 -4
  194. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  195. package/build/services/OtaUpdateCheckService.js +138 -22
  196. package/build/services/OtaUpdateCheckService.js.map +1 -1
  197. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  198. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  199. package/build/services/PhoneCalendarHelpers.js +157 -0
  200. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  201. package/build/services/PhoneCalendarService.d.ts +5 -0
  202. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  203. package/build/services/PhoneCalendarService.js +45 -0
  204. package/build/services/PhoneCalendarService.js.map +1 -0
  205. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  206. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  207. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  208. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  209. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  210. package/build/services/PhoneNotificationsSync.js +12 -10
  211. package/build/services/PhoneNotificationsSync.js.map +1 -1
  212. package/build/services/PhonePhotoCoordinator.d.ts +26 -2
  213. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  214. package/build/services/PhonePhotoCoordinator.js +79 -9
  215. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  216. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  217. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  218. package/build/services/PhoneStreamCoordinator.js +125 -13
  219. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  220. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  221. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  222. package/build/services/PhoneVideoCoordinator.js +10 -0
  223. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  224. package/build/services/SceneRenderer.d.ts.map +1 -1
  225. package/build/services/SceneRenderer.js +15 -0
  226. package/build/services/SceneRenderer.js.map +1 -1
  227. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  228. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  229. package/build/services/SentenceTtsPipeline.js +67 -0
  230. package/build/services/SentenceTtsPipeline.js.map +1 -0
  231. package/build/services/SupportProfileSync.d.ts +22 -0
  232. package/build/services/SupportProfileSync.d.ts.map +1 -0
  233. package/build/services/SupportProfileSync.js +213 -0
  234. package/build/services/SupportProfileSync.js.map +1 -0
  235. package/build/services/TranscriptionRouting.d.ts +12 -0
  236. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  237. package/build/services/TranscriptionRouting.js +24 -0
  238. package/build/services/TranscriptionRouting.js.map +1 -0
  239. package/build/services/TtsTextSanitizer.d.ts +5 -0
  240. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  241. package/build/services/TtsTextSanitizer.js +61 -0
  242. package/build/services/TtsTextSanitizer.js.map +1 -0
  243. package/build/services/WifiAdbRequest.d.ts +17 -0
  244. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  245. package/build/services/WifiAdbRequest.js +35 -0
  246. package/build/services/WifiAdbRequest.js.map +1 -0
  247. package/build/services/asg/asgCameraApi.d.ts +43 -0
  248. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  249. package/build/services/asg/asgCameraApi.js +509 -26
  250. package/build/services/asg/asgCameraApi.js.map +1 -1
  251. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  252. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  253. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  254. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  255. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  256. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  257. package/build/services/asg/cameraRollExportLedger.js +78 -0
  258. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  259. package/build/services/asg/galleryNotices.d.ts +1 -1
  260. package/build/services/asg/galleryNotices.d.ts.map +1 -1
  261. package/build/services/asg/galleryNotices.js.map +1 -1
  262. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  263. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  264. package/build/services/asg/galleryPathMigration.js +26 -0
  265. package/build/services/asg/galleryPathMigration.js.map +1 -0
  266. package/build/services/asg/gallerySettingsService.d.ts +1 -0
  267. package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
  268. package/build/services/asg/gallerySettingsService.js +2 -0
  269. package/build/services/asg/gallerySettingsService.js.map +1 -1
  270. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  271. package/build/services/asg/gallerySyncService.js +162 -56
  272. package/build/services/asg/gallerySyncService.js.map +1 -1
  273. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  274. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  275. package/build/services/asg/galleryTransferLedger.js +225 -0
  276. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  277. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  278. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  279. package/build/services/asg/localNetworkTransport.js +144 -0
  280. package/build/services/asg/localNetworkTransport.js.map +1 -0
  281. package/build/services/asg/localStorageService.d.ts +18 -0
  282. package/build/services/asg/localStorageService.d.ts.map +1 -1
  283. package/build/services/asg/localStorageService.js +168 -19
  284. package/build/services/asg/localStorageService.js.map +1 -1
  285. package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
  286. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
  287. package/build/services/asg/mediaProcessingQueue.js +193 -62
  288. package/build/services/asg/mediaProcessingQueue.js.map +1 -1
  289. package/build/services/audioPlaybackAssets.d.ts +8 -0
  290. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  291. package/build/services/audioPlaybackAssets.js +7 -0
  292. package/build/services/audioPlaybackAssets.js.map +1 -0
  293. package/build/services/gallerySyncClock.js +1 -1
  294. package/build/services/gallerySyncClock.js.map +1 -1
  295. package/build/services/glassesClockSync.d.ts.map +1 -1
  296. package/build/services/glassesClockSync.js +6 -2
  297. package/build/services/glassesClockSync.js.map +1 -1
  298. package/build/services/manifestActions.d.ts +7 -0
  299. package/build/services/manifestActions.d.ts.map +1 -0
  300. package/build/services/manifestActions.js +25 -0
  301. package/build/services/manifestActions.js.map +1 -0
  302. package/build/services/otaDisplayState.d.ts +23 -12
  303. package/build/services/otaDisplayState.d.ts.map +1 -1
  304. package/build/services/otaDisplayState.js +36 -14
  305. package/build/services/otaDisplayState.js.map +1 -1
  306. package/build/services/otaInstallPolicy.d.ts +16 -4
  307. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  308. package/build/services/otaInstallPolicy.js +24 -3
  309. package/build/services/otaInstallPolicy.js.map +1 -1
  310. package/build/services/otaLegacyMapping.d.ts +1 -1
  311. package/build/services/otaLegacyMapping.d.ts.map +1 -1
  312. package/build/services/otaLegacyMapping.js.map +1 -1
  313. package/build/services/otaManifestPolicy.d.ts +14 -0
  314. package/build/services/otaManifestPolicy.d.ts.map +1 -0
  315. package/build/services/otaManifestPolicy.js +19 -0
  316. package/build/services/otaManifestPolicy.js.map +1 -0
  317. package/build/services/otaManifestUrl.d.ts +3 -0
  318. package/build/services/otaManifestUrl.d.ts.map +1 -0
  319. package/build/services/otaManifestUrl.js +38 -0
  320. package/build/services/otaManifestUrl.js.map +1 -0
  321. package/build/services/slimStreamStatus.d.ts +11 -0
  322. package/build/services/slimStreamStatus.d.ts.map +1 -1
  323. package/build/services/slimStreamStatus.js +14 -4
  324. package/build/services/slimStreamStatus.js.map +1 -1
  325. package/build/stores/apps.d.ts.map +1 -1
  326. package/build/stores/apps.js +11 -0
  327. package/build/stores/apps.js.map +1 -1
  328. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  329. package/build/stores/bluetoothSettingKeys.js +2 -0
  330. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  331. package/build/stores/gallerySync.d.ts +2 -0
  332. package/build/stores/gallerySync.d.ts.map +1 -1
  333. package/build/stores/gallerySync.js +2 -0
  334. package/build/stores/gallerySync.js.map +1 -1
  335. package/build/stores/glasses.d.ts.map +1 -1
  336. package/build/stores/glasses.js +3 -0
  337. package/build/stores/glasses.js.map +1 -1
  338. package/build/stores/settings.d.ts +17 -0
  339. package/build/stores/settings.d.ts.map +1 -1
  340. package/build/stores/settings.js +157 -17
  341. package/build/stores/settings.js.map +1 -1
  342. package/build/types/applet.d.ts +2 -0
  343. package/build/types/applet.d.ts.map +1 -1
  344. package/build/types/applet.js.map +1 -1
  345. package/build/types/asg.d.ts +7 -0
  346. package/build/types/asg.d.ts.map +1 -1
  347. package/build/types/asg.js.map +1 -1
  348. package/build/types/enums.d.ts +2 -25
  349. package/build/types/enums.d.ts.map +1 -1
  350. package/build/types/enums.js +2 -27
  351. package/build/types/enums.js.map +1 -1
  352. package/build/types/hardware.d.ts +4 -13
  353. package/build/types/hardware.d.ts.map +1 -1
  354. package/build/types/hardware.js +15 -3
  355. package/build/types/hardware.js.map +1 -1
  356. package/build/types/index.d.ts +2 -6
  357. package/build/types/index.d.ts.map +1 -1
  358. package/build/types/index.js +2 -6
  359. package/build/types/index.js.map +1 -1
  360. package/build/utils/configuredDevHost.d.ts +6 -0
  361. package/build/utils/configuredDevHost.d.ts.map +1 -0
  362. package/build/utils/configuredDevHost.js +19 -0
  363. package/build/utils/configuredDevHost.js.map +1 -0
  364. package/build/utils/devMiniappLaunch.d.ts +19 -8
  365. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  366. package/build/utils/devMiniappLaunch.js +144 -21
  367. package/build/utils/devMiniappLaunch.js.map +1 -1
  368. package/build/utils/diagnosticContext.d.ts.map +1 -1
  369. package/build/utils/diagnosticContext.js +15 -17
  370. package/build/utils/diagnosticContext.js.map +1 -1
  371. package/build/utils/hardware/hardware.d.ts.map +1 -1
  372. package/build/utils/hardware/hardware.js +7 -3
  373. package/build/utils/hardware/hardware.js.map +1 -1
  374. package/build/utils/miniappDiagnostics.d.ts +64 -0
  375. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  376. package/build/utils/miniappDiagnostics.js +173 -0
  377. package/build/utils/miniappDiagnostics.js.map +1 -0
  378. package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
  379. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
  380. package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
  381. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
  382. package/build/utils/timers/timers.d.ts.map +1 -1
  383. package/build/utils/timers/timers.js +55 -18
  384. package/build/utils/timers/timers.js.map +1 -1
  385. package/package.json +59 -31
  386. package/src/assets/silence.wav +0 -0
  387. package/src/bluetooth-sdk/debug.ts +1 -0
  388. package/src/bluetooth-sdk/index.ts +2 -0
  389. package/src/bluetooth-sdk/photo-receiver.ts +2 -0
  390. package/src/bluetooth-sdk/react.ts +1 -0
  391. package/src/bluetooth-sdk/types.ts +1 -0
  392. package/src/engine.ts +9 -4
  393. package/src/facades/dev.ts +17 -12
  394. package/src/facades/display.ts +1 -1
  395. package/src/facades/gallery.ts +1 -1
  396. package/src/facades/glasses.ts +20 -7
  397. package/src/facades/glassesSettings.ts +5 -0
  398. package/src/facades/miniapps.ts +7 -0
  399. package/src/facades/ota.ts +23 -8
  400. package/src/facades/pairing.ts +15 -11
  401. package/src/facades/permissions.ts +14 -0
  402. package/src/facades/phoneNotifications.ts +4 -13
  403. package/src/facades/speech.ts +21 -7
  404. package/src/generated/releaseMetadata.ts +20 -0
  405. package/src/index.ts +39 -13
  406. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  407. package/src/react/index.ts +7 -0
  408. package/src/react/useEngineSnapshot.ts +16 -0
  409. package/src/runtime/bootstrap.ts +33 -1
  410. package/src/runtime/scanQrSeam.ts +20 -0
  411. package/src/services/AppRegistry.ts +240 -149
  412. package/src/services/AudioCloudUplink.ts +23 -1
  413. package/src/services/AudioPlaybackService.ts +287 -38
  414. package/src/services/BlobStore.ts +22 -9
  415. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  416. package/src/services/CloudClientService.ts +96 -1
  417. package/src/services/DeviceEventRouter.ts +5 -5
  418. package/src/services/ForegroundLocationPermission.ts +24 -0
  419. package/src/services/GlassesSettingsSync.ts +9 -3
  420. package/src/services/GlassesStatusProjection.ts +16 -8
  421. package/src/services/HotspotOtaTransport.ts +184 -0
  422. package/src/services/HotspotShutdown.ts +41 -0
  423. package/src/services/LocalDisplayManager.ts +112 -21
  424. package/src/services/LocalMiniappRuntime.ts +967 -346
  425. package/src/services/LocalMiniappStorage.ts +82 -0
  426. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  427. package/src/services/LocalSttFallbackCoordinator.ts +19 -12
  428. package/src/services/MicStateCoordinator.ts +169 -4
  429. package/src/services/MiniappLauncher.ts +30 -3
  430. package/src/services/MiniappLiveness.ts +24 -0
  431. package/src/services/NativeHttpResponse.ts +6 -0
  432. package/src/services/OtaArtifactDownloader.ts +312 -0
  433. package/src/services/OtaAutoChain.ts +106 -0
  434. package/src/services/OtaErrorMapping.ts +80 -0
  435. package/src/services/OtaInstallCoordinator.ts +649 -144
  436. package/src/services/OtaService.ts +11 -5
  437. package/src/services/OtaUpdateCheckService.ts +181 -21
  438. package/src/services/PhoneCalendarHelpers.ts +212 -0
  439. package/src/services/PhoneCalendarService.ts +65 -0
  440. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  441. package/src/services/PhoneNotificationsSync.ts +12 -10
  442. package/src/services/PhonePhotoCoordinator.ts +116 -18
  443. package/src/services/PhoneStreamCoordinator.ts +139 -25
  444. package/src/services/PhoneVideoCoordinator.ts +11 -0
  445. package/src/services/SceneRenderer.ts +16 -0
  446. package/src/services/SentenceTtsPipeline.ts +106 -0
  447. package/src/services/SupportProfileSync.ts +218 -0
  448. package/src/services/TranscriptionRouting.ts +37 -0
  449. package/src/services/TtsTextSanitizer.ts +66 -0
  450. package/src/services/WifiAdbRequest.ts +53 -0
  451. package/src/services/asg/asgCameraApi.ts +615 -33
  452. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  453. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  454. package/src/services/asg/galleryNotices.ts +1 -0
  455. package/src/services/asg/galleryPathMigration.ts +22 -0
  456. package/src/services/asg/gallerySettingsService.ts +3 -0
  457. package/src/services/asg/gallerySyncService.ts +184 -73
  458. package/src/services/asg/galleryTransferLedger.ts +312 -0
  459. package/src/services/asg/localNetworkTransport.ts +169 -0
  460. package/src/services/asg/localStorageService.ts +179 -24
  461. package/src/services/asg/mediaProcessingQueue.ts +209 -62
  462. package/src/services/audioPlaybackAssets.ts +8 -0
  463. package/src/services/gallerySyncClock.ts +1 -1
  464. package/src/services/glassesClockSync.ts +6 -2
  465. package/src/services/manifestActions.ts +30 -0
  466. package/src/services/otaDisplayState.ts +58 -17
  467. package/src/services/otaInstallPolicy.ts +30 -4
  468. package/src/services/otaLegacyMapping.ts +1 -1
  469. package/src/services/otaManifestPolicy.ts +42 -0
  470. package/src/services/otaManifestUrl.ts +44 -0
  471. package/src/services/slimStreamStatus.ts +16 -5
  472. package/src/stores/apps.ts +12 -0
  473. package/src/stores/bluetoothSettingKeys.ts +2 -0
  474. package/src/stores/gallerySync.ts +4 -0
  475. package/src/stores/glasses.ts +3 -0
  476. package/src/stores/settings.ts +179 -18
  477. package/src/types/applet.ts +2 -0
  478. package/src/types/asg.ts +7 -0
  479. package/src/types/enums.ts +3 -28
  480. package/src/types/hardware.ts +20 -13
  481. package/src/types/index.ts +2 -6
  482. package/src/utils/configuredDevHost.ts +17 -0
  483. package/src/utils/devMiniappLaunch.ts +151 -23
  484. package/src/utils/diagnosticContext.ts +17 -17
  485. package/src/utils/hardware/hardware.ts +7 -9
  486. package/src/utils/miniappDiagnostics.ts +226 -0
  487. package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
  488. package/src/utils/timers/timers.ts +57 -21
  489. package/build/devtools.d.ts +0 -11
  490. package/build/devtools.d.ts.map +0 -1
  491. package/build/devtools.js +0 -13
  492. package/build/devtools.js.map +0 -1
  493. package/build/internal.d.ts +0 -66
  494. package/build/internal.d.ts.map +0 -1
  495. package/build/internal.js +0 -89
  496. package/build/internal.js.map +0 -1
  497. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  498. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  499. package/build/services/asgOtaVersionUrl.js +0 -36
  500. package/build/services/asgOtaVersionUrl.js.map +0 -1
  501. package/src/devtools.ts +0 -13
  502. package/src/internal.ts +0 -158
  503. package/src/services/asgOtaVersionUrl.ts +0 -41
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Phone-local SimpleStorage for bundled miniapps.
3
+ *
4
+ * Keys are scoped to the stable Mentra user id and package name. Access tokens
5
+ * must never be part of the namespace: Core access tokens rotate and are held
6
+ * in memory only, so using one makes every app restart look like a new user.
7
+ */
8
+ export interface LocalMiniappStorageBackend {
9
+ get(key: string): unknown | null;
10
+ has(key: string): boolean;
11
+ set(key: string, value: unknown): void;
12
+ remove(key: string): void;
13
+ keys(): string[];
14
+ }
15
+ export interface LocalMiniappStorageHooks {
16
+ getUserId: () => Promise<string>;
17
+ backend: LocalMiniappStorageBackend;
18
+ }
19
+ export declare class LocalMiniappStorage {
20
+ private readonly hooks;
21
+ constructor(hooks: LocalMiniappStorageHooks);
22
+ get(packageName: string, key: string): Promise<unknown | null>;
23
+ set(packageName: string, key: string, value: unknown): Promise<void>;
24
+ delete(packageName: string, key: string): Promise<void>;
25
+ keys(packageName: string): Promise<string[]>;
26
+ clear(packageName: string): Promise<void>;
27
+ has(packageName: string, key: string): Promise<boolean>;
28
+ getAll(packageName: string): Promise<Record<string, string>>;
29
+ setMultiple(packageName: string, values: Record<string, unknown>): Promise<void>;
30
+ private prefix;
31
+ }
32
+ //# sourceMappingURL=LocalMiniappStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalMiniappStorage.d.ts","sourceRoot":"","sources":["../../src/services/LocalMiniappStorage.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,0BAA0B;IACzC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;IAChC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IACzB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IACtC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,IAAI,IAAI,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAChC,OAAO,EAAE,0BAA0B,CAAA;CACpC;AAID,qBAAa,mBAAmB;IAClB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,wBAAwB;IAEtD,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI9D,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAQ5C,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOzC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAY5D,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAOxE,MAAM;CAKrB"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Phone-local SimpleStorage for bundled miniapps.
3
+ *
4
+ * Keys are scoped to the stable Mentra user id and package name. Access tokens
5
+ * must never be part of the namespace: Core access tokens rotate and are held
6
+ * in memory only, so using one makes every app restart look like a new user.
7
+ */
8
+ const KEY_ROOT = "mentraos_localstorage_";
9
+ export class LocalMiniappStorage {
10
+ hooks;
11
+ constructor(hooks) {
12
+ this.hooks = hooks;
13
+ }
14
+ async get(packageName, key) {
15
+ return this.hooks.backend.get((await this.prefix(packageName)) + key);
16
+ }
17
+ async set(packageName, key, value) {
18
+ this.hooks.backend.set((await this.prefix(packageName)) + key, value);
19
+ }
20
+ async delete(packageName, key) {
21
+ this.hooks.backend.remove((await this.prefix(packageName)) + key);
22
+ }
23
+ async keys(packageName) {
24
+ const prefix = await this.prefix(packageName);
25
+ return this.hooks.backend
26
+ .keys()
27
+ .filter((key) => key.startsWith(prefix))
28
+ .map((key) => key.slice(prefix.length));
29
+ }
30
+ async clear(packageName) {
31
+ const prefix = await this.prefix(packageName);
32
+ for (const key of this.hooks.backend.keys()) {
33
+ if (key.startsWith(prefix))
34
+ this.hooks.backend.remove(key);
35
+ }
36
+ }
37
+ async has(packageName, key) {
38
+ return this.hooks.backend.has((await this.prefix(packageName)) + key);
39
+ }
40
+ async getAll(packageName) {
41
+ const prefix = await this.prefix(packageName);
42
+ const values = {};
43
+ for (const key of this.hooks.backend.keys()) {
44
+ if (!key.startsWith(prefix))
45
+ continue;
46
+ if (!this.hooks.backend.has(key))
47
+ continue;
48
+ const value = this.hooks.backend.get(key);
49
+ values[key.slice(prefix.length)] = typeof value === "string" ? value : String(value ?? "");
50
+ }
51
+ return values;
52
+ }
53
+ async setMultiple(packageName, values) {
54
+ const prefix = await this.prefix(packageName);
55
+ for (const [key, value] of Object.entries(values)) {
56
+ this.hooks.backend.set(prefix + key, value ?? null);
57
+ }
58
+ }
59
+ async prefix(packageName) {
60
+ const userId = (await this.hooks.getUserId()).trim();
61
+ if (!userId)
62
+ throw new Error("Mentra user identity is unavailable");
63
+ return `${KEY_ROOT}${userId}_${packageName}_`;
64
+ }
65
+ }
66
+ //# sourceMappingURL=LocalMiniappStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalMiniappStorage.js","sourceRoot":"","sources":["../../src/services/LocalMiniappStorage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Phone-local SimpleStorage for bundled miniapps.\n *\n * Keys are scoped to the stable Mentra user id and package name. Access tokens\n * must never be part of the namespace: Core access tokens rotate and are held\n * in memory only, so using one makes every app restart look like a new user.\n */\n\nexport interface LocalMiniappStorageBackend {\n get(key: string): unknown | null\n has(key: string): boolean\n set(key: string, value: unknown): void\n remove(key: string): void\n keys(): string[]\n}\n\nexport interface LocalMiniappStorageHooks {\n getUserId: () => Promise<string>\n backend: LocalMiniappStorageBackend\n}\n\nconst KEY_ROOT = \"mentraos_localstorage_\"\n\nexport class LocalMiniappStorage {\n constructor(private readonly hooks: LocalMiniappStorageHooks) {}\n\n async get(packageName: string, key: string): Promise<unknown | null> {\n return this.hooks.backend.get((await this.prefix(packageName)) + key)\n }\n\n async set(packageName: string, key: string, value: unknown): Promise<void> {\n this.hooks.backend.set((await this.prefix(packageName)) + key, value)\n }\n\n async delete(packageName: string, key: string): Promise<void> {\n this.hooks.backend.remove((await this.prefix(packageName)) + key)\n }\n\n async keys(packageName: string): Promise<string[]> {\n const prefix = await this.prefix(packageName)\n return this.hooks.backend\n .keys()\n .filter((key) => key.startsWith(prefix))\n .map((key) => key.slice(prefix.length))\n }\n\n async clear(packageName: string): Promise<void> {\n const prefix = await this.prefix(packageName)\n for (const key of this.hooks.backend.keys()) {\n if (key.startsWith(prefix)) this.hooks.backend.remove(key)\n }\n }\n\n async has(packageName: string, key: string): Promise<boolean> {\n return this.hooks.backend.has((await this.prefix(packageName)) + key)\n }\n\n async getAll(packageName: string): Promise<Record<string, string>> {\n const prefix = await this.prefix(packageName)\n const values: Record<string, string> = {}\n for (const key of this.hooks.backend.keys()) {\n if (!key.startsWith(prefix)) continue\n if (!this.hooks.backend.has(key)) continue\n const value = this.hooks.backend.get(key)\n values[key.slice(prefix.length)] = typeof value === \"string\" ? value : String(value ?? \"\")\n }\n return values\n }\n\n async setMultiple(packageName: string, values: Record<string, unknown>): Promise<void> {\n const prefix = await this.prefix(packageName)\n for (const [key, value] of Object.entries(values)) {\n this.hooks.backend.set(prefix + key, value ?? null)\n }\n }\n\n private async prefix(packageName: string): Promise<string> {\n const userId = (await this.hooks.getUserId()).trim()\n if (!userId) throw new Error(\"Mentra user identity is unavailable\")\n return `${KEY_ROOT}${userId}_${packageName}_`\n }\n}\n"]}
@@ -0,0 +1,20 @@
1
+ export interface LocalMiniappUserIdentityBackend {
2
+ get(): string | null;
3
+ set(userId: string): void;
4
+ remove(): void;
5
+ }
6
+ /**
7
+ * Keeps the stable Mentra user id available to local miniapps across process
8
+ * restarts. The id is non-secret and is deliberately stored separately from
9
+ * the short-lived Core access token.
10
+ */
11
+ export declare class LocalMiniappUserIdentity {
12
+ private readonly backend;
13
+ private current;
14
+ constructor(backend: LocalMiniappUserIdentityBackend);
15
+ resolve(resolveOnline: () => Promise<string>): Promise<string>;
16
+ get(): string | null;
17
+ remember(userId: string): void;
18
+ forget(): void;
19
+ }
20
+ //# sourceMappingURL=LocalMiniappUserIdentity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalMiniappUserIdentity.d.ts","sourceRoot":"","sources":["../../src/services/LocalMiniappUserIdentity.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,+BAA+B;IAC9C,GAAG,IAAI,MAAM,GAAG,IAAI,CAAA;IACpB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,IAAI,IAAI,CAAA;CACf;AAED;;;;GAIG;AACH,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,OAAO,CAAsB;gBAER,OAAO,EAAE,+BAA+B;IAE/D,OAAO,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAUpE,GAAG,IAAI,MAAM,GAAG,IAAI;IAQpB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAO9B,MAAM,IAAI,IAAI;CAIf"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Keeps the stable Mentra user id available to local miniapps across process
3
+ * restarts. The id is non-secret and is deliberately stored separately from
4
+ * the short-lived Core access token.
5
+ */
6
+ export class LocalMiniappUserIdentity {
7
+ backend;
8
+ current = null;
9
+ constructor(backend) {
10
+ this.backend = backend;
11
+ }
12
+ async resolve(resolveOnline) {
13
+ const available = this.get();
14
+ if (available)
15
+ return available;
16
+ const resolved = (await resolveOnline()).trim();
17
+ if (!resolved)
18
+ throw new Error("Mentra user identity is unavailable");
19
+ this.remember(resolved);
20
+ return resolved;
21
+ }
22
+ get() {
23
+ if (this.current)
24
+ return this.current;
25
+ const cached = this.backend.get()?.trim() ?? "";
26
+ if (!cached)
27
+ return null;
28
+ this.current = cached;
29
+ return cached;
30
+ }
31
+ remember(userId) {
32
+ const resolved = userId.trim();
33
+ if (!resolved)
34
+ throw new Error("Mentra user identity is unavailable");
35
+ this.backend.set(resolved);
36
+ this.current = resolved;
37
+ }
38
+ forget() {
39
+ this.current = null;
40
+ this.backend.remove();
41
+ }
42
+ }
43
+ //# sourceMappingURL=LocalMiniappUserIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalMiniappUserIdentity.js","sourceRoot":"","sources":["../../src/services/LocalMiniappUserIdentity.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,OAAO,wBAAwB;IAGN;IAFrB,OAAO,GAAkB,IAAI,CAAA;IAErC,YAA6B,OAAwC;QAAxC,YAAO,GAAP,OAAO,CAAiC;IAAG,CAAC;IAEzE,KAAK,CAAC,OAAO,CAAC,aAAoC;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QAC5B,IAAI,SAAS;YAAE,OAAO,SAAS,CAAA;QAE/B,MAAM,QAAQ,GAAG,CAAC,MAAM,aAAa,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;QAC/C,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;QACrE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACvB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,GAAG;QACD,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,OAAO,CAAA;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QAC/C,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QACrB,OAAO,MAAM,CAAA;IACf,CAAC;IAED,QAAQ,CAAC,MAAc;QACrB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;QAC9B,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;QACrE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC1B,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAA;IACzB,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;QACnB,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAA;IACvB,CAAC;CACF","sourcesContent":["export interface LocalMiniappUserIdentityBackend {\n get(): string | null\n set(userId: string): void\n remove(): void\n}\n\n/**\n * Keeps the stable Mentra user id available to local miniapps across process\n * restarts. The id is non-secret and is deliberately stored separately from\n * the short-lived Core access token.\n */\nexport class LocalMiniappUserIdentity {\n private current: string | null = null\n\n constructor(private readonly backend: LocalMiniappUserIdentityBackend) {}\n\n async resolve(resolveOnline: () => Promise<string>): Promise<string> {\n const available = this.get()\n if (available) return available\n\n const resolved = (await resolveOnline()).trim()\n if (!resolved) throw new Error(\"Mentra user identity is unavailable\")\n this.remember(resolved)\n return resolved\n }\n\n get(): string | null {\n if (this.current) return this.current\n const cached = this.backend.get()?.trim() ?? \"\"\n if (!cached) return null\n this.current = cached\n return cached\n }\n\n remember(userId: string): void {\n const resolved = userId.trim()\n if (!resolved) throw new Error(\"Mentra user identity is unavailable\")\n this.backend.set(resolved)\n this.current = resolved\n }\n\n forget(): void {\n this.current = null\n this.backend.remove()\n }\n}\n"]}
@@ -1,20 +1,22 @@
1
1
  /**
2
2
  * Decides whether on-device Sherpa STT should produce transcripts for local
3
- * miniapps, instead of (or in addition to) cloud transcription. The chooser
4
- * is connection-state-driven: when the WebSocket to cloud is down AND a
5
- * local miniapp is subscribed to transcription, we activate on-device STT.
3
+ * miniapps, instead of (or in addition to) cloud transcription. Local STT is
4
+ * active when the cloud is unavailable or any subscription requires
5
+ * `forceLocal`.
6
6
  *
7
7
  * Activation flips `localSttFallbackActive` in the settings store, which
8
8
  * the bluetooth-sdk native side reads to decide whether to feed PCM into
9
9
  * the SherpaOnnxTranscriber. Local transcripts then flow back through the
10
10
  * `local_transcription` Bridge event; the host wires that event to
11
11
  * `localMiniappRuntime.forwardEvent`, with this coordinator providing the
12
- * subscription-active gate so we never publish transcripts to miniapps
13
- * that aren't asking for them.
12
+ * subscription-active gate so we never publish transcripts to miniapps that
13
+ * aren't asking for them. LocalMiniappRuntime filters mixed local/cloud
14
+ * delivery per miniapp.
14
15
  */
15
16
  declare class LocalSttFallbackCoordinator {
16
17
  private static instance;
17
18
  private hasTranscriptionSubscription;
19
+ private hasForceLocalSubscription;
18
20
  private activeLanguage;
19
21
  /**
20
22
  * Default to "cloud is up" so we never accidentally activate local STT before
@@ -35,7 +37,7 @@ declare class LocalSttFallbackCoordinator {
35
37
  static getInstance(): LocalSttFallbackCoordinator;
36
38
  isActive(): boolean;
37
39
  getActiveLanguage(): string | null;
38
- onSubscriptionChange(hasTranscription: boolean, language: string | null): void;
40
+ onSubscriptionChange(hasTranscription: boolean, language: string | null, hasForceLocal?: boolean): void;
39
41
  /**
40
42
  * Informational hook, retained for API stability. No longer called: the
41
43
  * authoritative switching signal is the cloud-client adapter (local miniapps
@@ -47,6 +49,7 @@ declare class LocalSttFallbackCoordinator {
47
49
  private reconcile;
48
50
  private startLocalStt;
49
51
  private stopLocalStt;
52
+ private shouldUseLocalStt;
50
53
  private log;
51
54
  }
52
55
  declare const localSttFallbackCoordinator: LocalSttFallbackCoordinator;
@@ -1 +1 @@
1
- {"version":3,"file":"LocalSttFallbackCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/LocalSttFallbackCoordinator.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;GAaG;AACH,cAAM,2BAA2B;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IAEpD,OAAO,CAAC,4BAA4B,CAAQ;IAC5C,OAAO,CAAC,cAAc,CAAsB;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAO;IAC7B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,oBAAoB,CAAQ;IAEpC,OAAO;IAQP;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAajC,MAAM,CAAC,WAAW,IAAI,2BAA2B;IAOjD,QAAQ,IAAI,OAAO;IAInB,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIlC,oBAAoB,CAAC,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAO9E;;;;;;OAMG;IACH,iBAAiB,IAAI,IAAI;YAEX,SAAS;YAUT,aAAa;IAyB3B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,GAAG;CAGZ;AAED,QAAA,MAAM,2BAA2B,6BAA4C,CAAA;AAC7E,eAAe,2BAA2B,CAAA"}
1
+ {"version":3,"file":"LocalSttFallbackCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/LocalSttFallbackCoordinator.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;GAcG;AACH,cAAM,2BAA2B;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IAEpD,OAAO,CAAC,4BAA4B,CAAQ;IAC5C,OAAO,CAAC,yBAAyB,CAAQ;IACzC,OAAO,CAAC,cAAc,CAAsB;IAC5C;;;;;OAKG;IACH,OAAO,CAAC,cAAc,CAAO;IAC7B,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,oBAAoB,CAAQ;IAEpC,OAAO;IAQP;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAajC,MAAM,CAAC,WAAW,IAAI,2BAA2B;IAOjD,QAAQ,IAAI,OAAO;IAInB,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAIlC,oBAAoB,CAAC,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,aAAa,UAAQ,GAAG,IAAI;IAQrG;;;;;;OAMG;IACH,iBAAiB,IAAI,IAAI;YAEX,SAAS;YAUT,aAAa;IAyB3B,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,GAAG;CAGZ;AAED,QAAA,MAAM,2BAA2B,6BAA4C,CAAA;AAC7E,eAAe,2BAA2B,CAAA"}
@@ -5,21 +5,23 @@ import { cloudClientService } from "./CloudClientService";
5
5
  import sttModelManager from "./STTModelManager";
6
6
  /**
7
7
  * Decides whether on-device Sherpa STT should produce transcripts for local
8
- * miniapps, instead of (or in addition to) cloud transcription. The chooser
9
- * is connection-state-driven: when the WebSocket to cloud is down AND a
10
- * local miniapp is subscribed to transcription, we activate on-device STT.
8
+ * miniapps, instead of (or in addition to) cloud transcription. Local STT is
9
+ * active when the cloud is unavailable or any subscription requires
10
+ * `forceLocal`.
11
11
  *
12
12
  * Activation flips `localSttFallbackActive` in the settings store, which
13
13
  * the bluetooth-sdk native side reads to decide whether to feed PCM into
14
14
  * the SherpaOnnxTranscriber. Local transcripts then flow back through the
15
15
  * `local_transcription` Bridge event; the host wires that event to
16
16
  * `localMiniappRuntime.forwardEvent`, with this coordinator providing the
17
- * subscription-active gate so we never publish transcripts to miniapps
18
- * that aren't asking for them.
17
+ * subscription-active gate so we never publish transcripts to miniapps that
18
+ * aren't asking for them. LocalMiniappRuntime filters mixed local/cloud
19
+ * delivery per miniapp.
19
20
  */
20
21
  class LocalSttFallbackCoordinator {
21
22
  static instance;
22
23
  hasTranscriptionSubscription = false;
24
+ hasForceLocalSubscription = false;
23
25
  activeLanguage = null;
24
26
  /**
25
27
  * Default to "cloud is up" so we never accidentally activate local STT before
@@ -68,9 +70,10 @@ class LocalSttFallbackCoordinator {
68
70
  getActiveLanguage() {
69
71
  return this.activeLanguage;
70
72
  }
71
- onSubscriptionChange(hasTranscription, language) {
72
- this.log(`onSubscriptionChange(hasTx=${hasTranscription}, lang=${language})`);
73
+ onSubscriptionChange(hasTranscription, language, hasForceLocal = false) {
74
+ this.log(`onSubscriptionChange(hasTx=${hasTranscription}, lang=${language}, forceLocal=${hasForceLocal})`);
73
75
  this.hasTranscriptionSubscription = hasTranscription;
76
+ this.hasForceLocalSubscription = hasTranscription && hasForceLocal;
74
77
  this.activeLanguage = hasTranscription ? language : null;
75
78
  void this.reconcile();
76
79
  }
@@ -84,7 +87,7 @@ class LocalSttFallbackCoordinator {
84
87
  onCloudTranscript() { }
85
88
  async reconcile() {
86
89
  this.attachCloudAdapterIfReady();
87
- const shouldBeActive = this.hasTranscriptionSubscription && !this.cloudConnected;
90
+ const shouldBeActive = this.shouldUseLocalStt();
88
91
  if (shouldBeActive && !this.localActive) {
89
92
  await this.startLocalStt();
90
93
  }
@@ -99,8 +102,8 @@ class LocalSttFallbackCoordinator {
99
102
  this.log("local stt model is not available yet — skipping activation");
100
103
  return;
101
104
  }
102
- if (!this.hasTranscriptionSubscription || this.cloudConnected) {
103
- this.log("local stt activation skipped: cloud recovered before start completed");
105
+ if (!this.shouldUseLocalStt()) {
106
+ this.log("local stt activation skipped: routing changed before start completed");
104
107
  return;
105
108
  }
106
109
  try {
@@ -110,8 +113,8 @@ class LocalSttFallbackCoordinator {
110
113
  catch (err) {
111
114
  this.log(`restartTranscriber failed: ${err}`);
112
115
  }
113
- if (!this.hasTranscriptionSubscription || this.cloudConnected) {
114
- this.log("local stt activation skipped: cloud recovered during transcriber restart");
116
+ if (!this.shouldUseLocalStt()) {
117
+ this.log("local stt activation skipped: routing changed during transcriber restart");
115
118
  return;
116
119
  }
117
120
  useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, true);
@@ -122,6 +125,9 @@ class LocalSttFallbackCoordinator {
122
125
  useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, false);
123
126
  this.localActive = false;
124
127
  }
128
+ shouldUseLocalStt() {
129
+ return this.hasTranscriptionSubscription && (this.hasForceLocalSubscription || !this.cloudConnected);
130
+ }
125
131
  log(msg) {
126
132
  console.log(`[LocalSttFallback] ${msg}`);
127
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"LocalSttFallbackCoordinator.js","sourceRoot":"","sources":["../../src/services/LocalSttFallbackCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {ISLAND_SETTINGS_KEYS} from \"../runtime/config\"\nimport {useSettingsStore} from \"../stores/settings\"\nimport {cloudClientService} from \"./CloudClientService\"\nimport sttModelManager from \"./STTModelManager\"\n\n/**\n * Decides whether on-device Sherpa STT should produce transcripts for local\n * miniapps, instead of (or in addition to) cloud transcription. The chooser\n * is connection-state-driven: when the WebSocket to cloud is down AND a\n * local miniapp is subscribed to transcription, we activate on-device STT.\n *\n * Activation flips `localSttFallbackActive` in the settings store, which\n * the bluetooth-sdk native side reads to decide whether to feed PCM into\n * the SherpaOnnxTranscriber. Local transcripts then flow back through the\n * `local_transcription` Bridge event; the host wires that event to\n * `localMiniappRuntime.forwardEvent`, with this coordinator providing the\n * subscription-active gate so we never publish transcripts to miniapps\n * that aren't asking for them.\n */\nclass LocalSttFallbackCoordinator {\n private static instance: LocalSttFallbackCoordinator\n\n private hasTranscriptionSubscription = false\n private activeLanguage: string | null = null\n /**\n * Default to \"cloud is up\" so we never accidentally activate local STT before\n * the cloud client has had a chance to start. We attach lazily on the first\n * subscription/reconcile pass; once attached, this field reflects the real\n * cloud-client runtime status.\n */\n private cloudConnected = true\n private localActive = false\n private cloudAdapterAttached = false\n\n private constructor() {\n // Reset the persisted mirror flag on boot — the in-memory state in this\n // coordinator is the source of truth, and a stale \"true\" left from the\n // previous session would cause native to feed Sherpa before any miniapp\n // registered a subscription.\n useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, false)\n }\n\n /**\n * Lazy-attach the engine cloud connection listener. The coordinator is\n * constructed at module load, before engine.start() brings up the cloud\n * client, so we defer until the first reconcile.\n */\n private attachCloudAdapterIfReady(): void {\n if (this.cloudAdapterAttached) return\n this.cloudConnected = cloudClientService.isConnected()\n cloudClientService.onStatusChanged((status) => {\n const connected = status.status === \"connected\"\n if (this.cloudConnected === connected) return\n this.log(`cloud connection -> ${connected ? \"up\" : \"down\"}`)\n this.cloudConnected = connected\n void this.reconcile()\n })\n this.cloudAdapterAttached = true\n }\n\n static getInstance(): LocalSttFallbackCoordinator {\n if (!LocalSttFallbackCoordinator.instance) {\n LocalSttFallbackCoordinator.instance = new LocalSttFallbackCoordinator()\n }\n return LocalSttFallbackCoordinator.instance\n }\n\n isActive(): boolean {\n return this.localActive\n }\n\n getActiveLanguage(): string | null {\n return this.activeLanguage\n }\n\n onSubscriptionChange(hasTranscription: boolean, language: string | null): void {\n this.log(`onSubscriptionChange(hasTx=${hasTranscription}, lang=${language})`)\n this.hasTranscriptionSubscription = hasTranscription\n this.activeLanguage = hasTranscription ? language : null\n void this.reconcile()\n }\n\n /**\n * Informational hook, retained for API stability. No longer called: the\n * authoritative switching signal is the cloud-client adapter (local miniapps\n * are powered only by V2). v1 cloud transcripts deliberately do NOT drive this\n * coordinator anymore. Kept for future hysteresis if connection-state alone\n * proves too coarse.\n */\n onCloudTranscript(): void {}\n\n private async reconcile(): Promise<void> {\n this.attachCloudAdapterIfReady()\n const shouldBeActive = this.hasTranscriptionSubscription && !this.cloudConnected\n if (shouldBeActive && !this.localActive) {\n await this.startLocalStt()\n } else if (!shouldBeActive && this.localActive) {\n this.stopLocalStt(this.hasTranscriptionSubscription ? \"cloud reconnected\" : \"subscription gone\")\n }\n }\n\n private async startLocalStt(): Promise<void> {\n this.log(\"starting local stt\")\n const modelAvailable = await sttModelManager.isModelAvailable()\n if (!modelAvailable) {\n this.log(\"local stt model is not available yet — skipping activation\")\n return\n }\n if (!this.hasTranscriptionSubscription || this.cloudConnected) {\n this.log(\"local stt activation skipped: cloud recovered before start completed\")\n return\n }\n try {\n // Direct btsdk call now (was a host restartTranscriber hook).\n await BluetoothSdk.restartTranscriber()\n } catch (err) {\n this.log(`restartTranscriber failed: ${err}`)\n }\n if (!this.hasTranscriptionSubscription || this.cloudConnected) {\n this.log(\"local stt activation skipped: cloud recovered during transcriber restart\")\n return\n }\n useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, true)\n this.localActive = true\n }\n\n private stopLocalStt(reason: string): void {\n this.log(`stopping local stt: ${reason}`)\n useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, false)\n this.localActive = false\n }\n\n private log(msg: string): void {\n console.log(`[LocalSttFallback] ${msg}`)\n }\n}\n\nconst localSttFallbackCoordinator = LocalSttFallbackCoordinator.getInstance()\nexport default localSttFallbackCoordinator\n"]}
1
+ {"version":3,"file":"LocalSttFallbackCoordinator.js","sourceRoot":"","sources":["../../src/services/LocalSttFallbackCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {ISLAND_SETTINGS_KEYS} from \"../runtime/config\"\nimport {useSettingsStore} from \"../stores/settings\"\nimport {cloudClientService} from \"./CloudClientService\"\nimport sttModelManager from \"./STTModelManager\"\n\n/**\n * Decides whether on-device Sherpa STT should produce transcripts for local\n * miniapps, instead of (or in addition to) cloud transcription. Local STT is\n * active when the cloud is unavailable or any subscription requires\n * `forceLocal`.\n *\n * Activation flips `localSttFallbackActive` in the settings store, which\n * the bluetooth-sdk native side reads to decide whether to feed PCM into\n * the SherpaOnnxTranscriber. Local transcripts then flow back through the\n * `local_transcription` Bridge event; the host wires that event to\n * `localMiniappRuntime.forwardEvent`, with this coordinator providing the\n * subscription-active gate so we never publish transcripts to miniapps that\n * aren't asking for them. LocalMiniappRuntime filters mixed local/cloud\n * delivery per miniapp.\n */\nclass LocalSttFallbackCoordinator {\n private static instance: LocalSttFallbackCoordinator\n\n private hasTranscriptionSubscription = false\n private hasForceLocalSubscription = false\n private activeLanguage: string | null = null\n /**\n * Default to \"cloud is up\" so we never accidentally activate local STT before\n * the cloud client has had a chance to start. We attach lazily on the first\n * subscription/reconcile pass; once attached, this field reflects the real\n * cloud-client runtime status.\n */\n private cloudConnected = true\n private localActive = false\n private cloudAdapterAttached = false\n\n private constructor() {\n // Reset the persisted mirror flag on boot — the in-memory state in this\n // coordinator is the source of truth, and a stale \"true\" left from the\n // previous session would cause native to feed Sherpa before any miniapp\n // registered a subscription.\n useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, false)\n }\n\n /**\n * Lazy-attach the engine cloud connection listener. The coordinator is\n * constructed at module load, before engine.start() brings up the cloud\n * client, so we defer until the first reconcile.\n */\n private attachCloudAdapterIfReady(): void {\n if (this.cloudAdapterAttached) return\n this.cloudConnected = cloudClientService.isConnected()\n cloudClientService.onStatusChanged((status) => {\n const connected = status.status === \"connected\"\n if (this.cloudConnected === connected) return\n this.log(`cloud connection -> ${connected ? \"up\" : \"down\"}`)\n this.cloudConnected = connected\n void this.reconcile()\n })\n this.cloudAdapterAttached = true\n }\n\n static getInstance(): LocalSttFallbackCoordinator {\n if (!LocalSttFallbackCoordinator.instance) {\n LocalSttFallbackCoordinator.instance = new LocalSttFallbackCoordinator()\n }\n return LocalSttFallbackCoordinator.instance\n }\n\n isActive(): boolean {\n return this.localActive\n }\n\n getActiveLanguage(): string | null {\n return this.activeLanguage\n }\n\n onSubscriptionChange(hasTranscription: boolean, language: string | null, hasForceLocal = false): void {\n this.log(`onSubscriptionChange(hasTx=${hasTranscription}, lang=${language}, forceLocal=${hasForceLocal})`)\n this.hasTranscriptionSubscription = hasTranscription\n this.hasForceLocalSubscription = hasTranscription && hasForceLocal\n this.activeLanguage = hasTranscription ? language : null\n void this.reconcile()\n }\n\n /**\n * Informational hook, retained for API stability. No longer called: the\n * authoritative switching signal is the cloud-client adapter (local miniapps\n * are powered only by V2). v1 cloud transcripts deliberately do NOT drive this\n * coordinator anymore. Kept for future hysteresis if connection-state alone\n * proves too coarse.\n */\n onCloudTranscript(): void {}\n\n private async reconcile(): Promise<void> {\n this.attachCloudAdapterIfReady()\n const shouldBeActive = this.shouldUseLocalStt()\n if (shouldBeActive && !this.localActive) {\n await this.startLocalStt()\n } else if (!shouldBeActive && this.localActive) {\n this.stopLocalStt(this.hasTranscriptionSubscription ? \"cloud reconnected\" : \"subscription gone\")\n }\n }\n\n private async startLocalStt(): Promise<void> {\n this.log(\"starting local stt\")\n const modelAvailable = await sttModelManager.isModelAvailable()\n if (!modelAvailable) {\n this.log(\"local stt model is not available yet — skipping activation\")\n return\n }\n if (!this.shouldUseLocalStt()) {\n this.log(\"local stt activation skipped: routing changed before start completed\")\n return\n }\n try {\n // Direct btsdk call now (was a host restartTranscriber hook).\n await BluetoothSdk.restartTranscriber()\n } catch (err) {\n this.log(`restartTranscriber failed: ${err}`)\n }\n if (!this.shouldUseLocalStt()) {\n this.log(\"local stt activation skipped: routing changed during transcriber restart\")\n return\n }\n useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, true)\n this.localActive = true\n }\n\n private stopLocalStt(reason: string): void {\n this.log(`stopping local stt: ${reason}`)\n useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, false)\n this.localActive = false\n }\n\n private shouldUseLocalStt(): boolean {\n return this.hasTranscriptionSubscription && (this.hasForceLocalSubscription || !this.cloudConnected)\n }\n\n private log(msg: string): void {\n console.log(`[LocalSttFallback] ${msg}`)\n }\n}\n\nconst localSttFallbackCoordinator = LocalSttFallbackCoordinator.getInstance()\nexport default localSttFallbackCoordinator\n"]}
@@ -7,10 +7,20 @@
7
7
  * This coordinator pushes the aggregate local requirement set to BluetoothSdk
8
8
  * so the mic runs whenever at least one local consumer needs it.
9
9
  */
10
+ type MicGate = "vad" | "loudnessGate";
11
+ interface ConfiguredMicGates {
12
+ vadEnabled?: boolean | null;
13
+ loudnessGateEnabled?: boolean | null;
14
+ }
10
15
  declare class MicStateCoordinator {
11
16
  private static instance;
12
17
  private localWantsPcm;
13
18
  private localWantsLc3;
19
+ private configuredVad;
20
+ private configuredLoudnessGate;
21
+ private readonly miniappVadOverrides;
22
+ private readonly miniappLoudnessGateOverrides;
23
+ private overrideSequence;
14
24
  private constructor();
15
25
  static getInstance(): MicStateCoordinator;
16
26
  /**
@@ -20,12 +30,43 @@ declare class MicStateCoordinator {
20
30
  setLocalRequirements(req: {
21
31
  pcm: boolean;
22
32
  lc3: boolean;
23
- }): void;
33
+ } & ConfiguredMicGates): void;
34
+ /**
35
+ * Apply a miniapp-owned gate override without changing the OS preference.
36
+ * Overrides are lifecycle-scoped and last-live-owner-wins independently for
37
+ * VAD and Barrier.
38
+ */
39
+ setMiniappGateOverride(packageName: string, gate: MicGate, enabled: boolean, configured?: ConfiguredMicGates): Promise<void>;
40
+ /**
41
+ * Remove every gate override owned by a miniapp. This is synchronous so
42
+ * unregister can drop ownership before recomputing aggregate mic state.
43
+ */
44
+ clearMiniappGateOverrides(packageName: string): boolean;
45
+ /** Re-apply the current runtime policy after an owner is released. */
46
+ syncEffectiveGatePolicy(configured?: ConfiguredMicGates): Promise<void>;
47
+ /**
48
+ * Preserve the runtime microphone contract when the persisted device
49
+ * settings are replayed (for example after a glasses reconnect). Active
50
+ * miniapp gate overrides replace the OS values, and raw PCM keeps VAD off
51
+ * until the last raw-audio consumer unsubscribes.
52
+ */
53
+ applyRuntimeOverrides(settings: Record<string, unknown>): Record<string, unknown>;
54
+ /**
55
+ * Apply the complete current gate policy without treating the input as an OS
56
+ * preference update. Used by debounced mic-requirement writes, whose queued
57
+ * gate values may be stale after an override is acquired or released.
58
+ */
59
+ applyEffectiveGatePolicy(settings: Record<string, unknown>): Record<string, unknown>;
60
+ private applyActiveRuntimeOverrides;
24
61
  /**
25
62
  * Push local requirements to BluetoothSdk. `should_send_pcm` is strictly for
26
63
  * on-device PCM consumers; cloud audio uses LC3 through AudioCloudUplink.
27
64
  */
28
65
  private applyUnion;
66
+ private rememberConfiguredGates;
67
+ private overridesFor;
68
+ private latestOverride;
69
+ private effectiveGatePatch;
29
70
  /**
30
71
  * Reset all requirements to off. Called during cleanup.
31
72
  */
@@ -1 +1 @@
1
- {"version":3,"file":"MicStateCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/MicStateCoordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmC;IAG1D,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,aAAa,CAAQ;IAE7B,OAAO;WAEO,WAAW,IAAI,mBAAmB;IAOhD;;;OAGG;IACI,oBAAoB,CAAC,GAAG,EAAE;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAC,GAAG,IAAI;IAOpE;;;OAGG;IACH,OAAO,CAAC,UAAU;IAiBlB;;OAEG;IACI,KAAK,IAAI,IAAI;IAMb,OAAO,IAAI,IAAI;CAKvB;AAED,QAAA,MAAM,mBAAmB,qBAAoC,CAAA;AAC7D,eAAe,mBAAmB,CAAA"}
1
+ {"version":3,"file":"MicStateCoordinator.d.ts","sourceRoot":"","sources":["../../src/services/MicStateCoordinator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,KAAK,OAAO,GAAG,KAAK,GAAG,cAAc,CAAA;AAOrC,UAAU,kBAAkB;IAC1B,UAAU,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IAC3B,mBAAmB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CACrC;AAkBD,cAAM,mBAAmB;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmC;IAG1D,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,sBAAsB,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAkC;IACtE,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAkC;IAC/E,OAAO,CAAC,gBAAgB,CAAI;IAE5B,OAAO;WAEO,WAAW,IAAI,mBAAmB;IAOhD;;;OAGG;IACI,oBAAoB,CAAC,GAAG,EAAE;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAC,GAAG,kBAAkB,GAAG,IAAI;IAQzF;;;;OAIG;IACU,sBAAsB,CACjC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,OAAO,EAChB,UAAU,GAAE,kBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC;IAoBhB;;;OAGG;IACI,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAM9D,sEAAsE;IACzD,uBAAuB,CAAC,UAAU,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxF;;;;;OAKG;IACI,qBAAqB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAaxF;;;;OAIG;IACI,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAO3F,OAAO,CAAC,2BAA2B;IAiBnC;;;OAGG;IACH,OAAO,CAAC,UAAU;IAoBlB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,kBAAkB;IAmB1B;;OAEG;IACI,KAAK,IAAI,IAAI;IAMb,OAAO,IAAI,IAAI;CAOvB;AAED,QAAA,MAAM,mBAAmB,qBAAoC,CAAA;AAC7D,eAAe,mBAAmB,CAAA"}
@@ -14,7 +14,11 @@ const LOG_TAG = "MIC_COORDINATOR";
14
14
  * (wire v2 keeps BLE JSON small and infrequent). */
15
15
  const flushMicRequirementsPatch = createDebouncedPatchFlusher((patch) => {
16
16
  try {
17
- void Promise.resolve(BluetoothSdk.updateBluetoothSettings(patch)).catch((err) => {
17
+ // Resolve runtime overrides at flush time. A miniapp can acquire/release a
18
+ // gate override during the debounce window, and a captured stale value
19
+ // must not win after that lifecycle transition.
20
+ const runtimePatch = micStateCoordinator.applyEffectiveGatePolicy(patch);
21
+ void Promise.resolve(BluetoothSdk.updateBluetoothSettings(runtimePatch)).catch((err) => {
18
22
  console.error(`${LOG_TAG}: failed to apply mic requirements:`, err);
19
23
  });
20
24
  }
@@ -27,6 +31,11 @@ class MicStateCoordinator {
27
31
  // Local miniapp requirements (set when miniapps subscribe to audio streams)
28
32
  localWantsPcm = false;
29
33
  localWantsLc3 = false;
34
+ configuredVad;
35
+ configuredLoudnessGate;
36
+ miniappVadOverrides = new Map();
37
+ miniappLoudnessGateOverrides = new Map();
38
+ overrideSequence = 0;
30
39
  constructor() { }
31
40
  static getInstance() {
32
41
  if (!MicStateCoordinator.instance) {
@@ -41,9 +50,94 @@ class MicStateCoordinator {
41
50
  setLocalRequirements(req) {
42
51
  this.localWantsPcm = req.pcm;
43
52
  this.localWantsLc3 = req.lc3;
53
+ this.rememberConfiguredGates(req);
44
54
  console.log(`${LOG_TAG}: local requirements updated — pcm=${req.pcm} lc3=${req.lc3}`);
45
55
  this.applyUnion();
46
56
  }
57
+ /**
58
+ * Apply a miniapp-owned gate override without changing the OS preference.
59
+ * Overrides are lifecycle-scoped and last-live-owner-wins independently for
60
+ * VAD and Barrier.
61
+ */
62
+ async setMiniappGateOverride(packageName, gate, enabled, configured = {}) {
63
+ this.rememberConfiguredGates(configured);
64
+ const overrides = this.overridesFor(gate);
65
+ const previous = overrides.get(packageName);
66
+ const next = { enabled, order: ++this.overrideSequence };
67
+ overrides.set(packageName, next);
68
+ try {
69
+ await BluetoothSdk.updateBluetoothSettings(this.effectiveGatePatch());
70
+ }
71
+ catch (error) {
72
+ // Do not roll back a newer request from the same package that landed
73
+ // while this native write was in flight.
74
+ if (overrides.get(packageName) === next) {
75
+ if (previous)
76
+ overrides.set(packageName, previous);
77
+ else
78
+ overrides.delete(packageName);
79
+ }
80
+ throw error;
81
+ }
82
+ }
83
+ /**
84
+ * Remove every gate override owned by a miniapp. This is synchronous so
85
+ * unregister can drop ownership before recomputing aggregate mic state.
86
+ */
87
+ clearMiniappGateOverrides(packageName) {
88
+ const removedVad = this.miniappVadOverrides.delete(packageName);
89
+ const removedLoudness = this.miniappLoudnessGateOverrides.delete(packageName);
90
+ return removedVad || removedLoudness;
91
+ }
92
+ /** Re-apply the current runtime policy after an owner is released. */
93
+ async syncEffectiveGatePolicy(configured = {}) {
94
+ this.rememberConfiguredGates(configured);
95
+ const patch = this.effectiveGatePatch();
96
+ if (Object.keys(patch).length === 0)
97
+ return;
98
+ await BluetoothSdk.updateBluetoothSettings(patch);
99
+ }
100
+ /**
101
+ * Preserve the runtime microphone contract when the persisted device
102
+ * settings are replayed (for example after a glasses reconnect). Active
103
+ * miniapp gate overrides replace the OS values, and raw PCM keeps VAD off
104
+ * until the last raw-audio consumer unsubscribes.
105
+ */
106
+ applyRuntimeOverrides(settings) {
107
+ this.rememberConfiguredGates({
108
+ vadEnabled: typeof settings.voice_activity_detection_enabled === "boolean"
109
+ ? settings.voice_activity_detection_enabled
110
+ : undefined,
111
+ loudnessGateEnabled: typeof settings.loudness_gate_enabled === "boolean" ? settings.loudness_gate_enabled : undefined,
112
+ });
113
+ return this.applyActiveRuntimeOverrides(settings);
114
+ }
115
+ /**
116
+ * Apply the complete current gate policy without treating the input as an OS
117
+ * preference update. Used by debounced mic-requirement writes, whose queued
118
+ * gate values may be stale after an override is acquired or released.
119
+ */
120
+ applyEffectiveGatePolicy(settings) {
121
+ return {
122
+ ...settings,
123
+ ...this.effectiveGatePatch(),
124
+ };
125
+ }
126
+ applyActiveRuntimeOverrides(settings) {
127
+ const runtimeSettings = { ...settings };
128
+ const vadOverride = this.latestOverride(this.miniappVadOverrides);
129
+ const loudnessOverride = this.latestOverride(this.miniappLoudnessGateOverrides);
130
+ if (this.localWantsPcm) {
131
+ runtimeSettings.voice_activity_detection_enabled = false;
132
+ }
133
+ else if (vadOverride) {
134
+ runtimeSettings.voice_activity_detection_enabled = vadOverride.enabled;
135
+ }
136
+ if (loudnessOverride) {
137
+ runtimeSettings.loudness_gate_enabled = loudnessOverride.enabled;
138
+ }
139
+ return runtimeSettings;
140
+ }
47
141
  /**
48
142
  * Push local requirements to BluetoothSdk. `should_send_pcm` is strictly for
49
143
  * on-device PCM consumers; cloud audio uses LC3 through AudioCloudUplink.
@@ -56,11 +150,53 @@ class MicStateCoordinator {
56
150
  // )
57
151
  // The mic control plane is a direct btsdk call now (was a host setMicRequirements
58
152
  // hook) so a bare OEM streams audio without wiring it.
59
- flushMicRequirementsPatch({
153
+ const patch = {
60
154
  should_send_pcm: shouldSendPcm,
61
155
  should_send_lc3: shouldSendLc3,
62
156
  should_send_transcript: false,
63
- });
157
+ ...this.effectiveGatePatch(),
158
+ };
159
+ flushMicRequirementsPatch(patch);
160
+ }
161
+ rememberConfiguredGates(configured) {
162
+ // null means the connected device intentionally omits that setting.
163
+ // undefined means the caller is not updating the remembered preference.
164
+ if (configured.vadEnabled !== undefined) {
165
+ this.configuredVad = configured.vadEnabled ?? undefined;
166
+ }
167
+ if (configured.loudnessGateEnabled !== undefined) {
168
+ this.configuredLoudnessGate = configured.loudnessGateEnabled ?? undefined;
169
+ }
170
+ }
171
+ overridesFor(gate) {
172
+ return gate === "vad" ? this.miniappVadOverrides : this.miniappLoudnessGateOverrides;
173
+ }
174
+ latestOverride(overrides) {
175
+ let latest;
176
+ for (const entry of overrides.values()) {
177
+ if (!latest || entry.order > latest.order)
178
+ latest = entry;
179
+ }
180
+ return latest;
181
+ }
182
+ effectiveGatePatch() {
183
+ const patch = {};
184
+ const vadOverride = this.latestOverride(this.miniappVadOverrides);
185
+ const loudnessOverride = this.latestOverride(this.miniappLoudnessGateOverrides);
186
+ // Hardware VAD suppresses silence. Raw-audio consumers need a continuous
187
+ // timeline, so their requirement wins over both OS and miniapp VAD values.
188
+ if (this.localWantsPcm)
189
+ patch.voice_activity_detection_enabled = false;
190
+ else if (vadOverride)
191
+ patch.voice_activity_detection_enabled = vadOverride.enabled;
192
+ else if (this.configuredVad !== undefined)
193
+ patch.voice_activity_detection_enabled = this.configuredVad;
194
+ if (loudnessOverride)
195
+ patch.loudness_gate_enabled = loudnessOverride.enabled;
196
+ else if (this.configuredLoudnessGate !== undefined) {
197
+ patch.loudness_gate_enabled = this.configuredLoudnessGate;
198
+ }
199
+ return patch;
64
200
  }
65
201
  /**
66
202
  * Reset all requirements to off. Called during cleanup.
@@ -72,6 +208,8 @@ class MicStateCoordinator {
72
208
  }
73
209
  cleanup() {
74
210
  console.log(`${LOG_TAG}: cleanup()`);
211
+ this.miniappVadOverrides.clear();
212
+ this.miniappLoudnessGateOverrides.clear();
75
213
  this.reset();
76
214
  MicStateCoordinator.instance = null;
77
215
  }