@mentra/engine 0.1.0-dev.0 → 3.1.0-beta.100

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 (574) hide show
  1. package/README.md +73 -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/ota-transport.d.ts +2 -0
  11. package/build/bluetooth-sdk/ota-transport.d.ts.map +1 -0
  12. package/build/bluetooth-sdk/ota-transport.js +2 -0
  13. package/build/bluetooth-sdk/ota-transport.js.map +1 -0
  14. package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
  15. package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
  16. package/build/bluetooth-sdk/photo-receiver.js +3 -0
  17. package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
  18. package/build/bluetooth-sdk/react.d.ts +2 -0
  19. package/build/bluetooth-sdk/react.d.ts.map +1 -0
  20. package/build/bluetooth-sdk/react.js +2 -0
  21. package/build/bluetooth-sdk/react.js.map +1 -0
  22. package/build/bluetooth-sdk/types.d.ts +2 -0
  23. package/build/bluetooth-sdk/types.d.ts.map +1 -0
  24. package/build/bluetooth-sdk/types.js +2 -0
  25. package/build/bluetooth-sdk/types.js.map +1 -0
  26. package/build/engine.d.ts +29 -18
  27. package/build/engine.d.ts.map +1 -1
  28. package/build/engine.js +9 -4
  29. package/build/engine.js.map +1 -1
  30. package/build/facades/dev.d.ts +3 -2
  31. package/build/facades/dev.d.ts.map +1 -1
  32. package/build/facades/dev.js +18 -12
  33. package/build/facades/dev.js.map +1 -1
  34. package/build/facades/display.d.ts +1 -1
  35. package/build/facades/display.d.ts.map +1 -1
  36. package/build/facades/display.js +1 -1
  37. package/build/facades/display.js.map +1 -1
  38. package/build/facades/gallery.js +1 -1
  39. package/build/facades/gallery.js.map +1 -1
  40. package/build/facades/glasses.d.ts +4 -13
  41. package/build/facades/glasses.d.ts.map +1 -1
  42. package/build/facades/glasses.js +21 -6
  43. package/build/facades/glasses.js.map +1 -1
  44. package/build/facades/glassesSettings.d.ts.map +1 -1
  45. package/build/facades/glassesSettings.js +1 -0
  46. package/build/facades/glassesSettings.js.map +1 -1
  47. package/build/facades/miniapps.d.ts +4 -0
  48. package/build/facades/miniapps.d.ts.map +1 -1
  49. package/build/facades/miniapps.js +5 -0
  50. package/build/facades/miniapps.js.map +1 -1
  51. package/build/facades/ota.d.ts +24 -21
  52. package/build/facades/ota.d.ts.map +1 -1
  53. package/build/facades/ota.js +31 -12
  54. package/build/facades/ota.js.map +1 -1
  55. package/build/facades/pairing.d.ts +12 -5
  56. package/build/facades/pairing.d.ts.map +1 -1
  57. package/build/facades/pairing.js +93 -17
  58. package/build/facades/pairing.js.map +1 -1
  59. package/build/facades/permissions.d.ts +10 -0
  60. package/build/facades/permissions.d.ts.map +1 -1
  61. package/build/facades/permissions.js +10 -0
  62. package/build/facades/permissions.js.map +1 -1
  63. package/build/facades/phoneNotifications.d.ts +0 -4
  64. package/build/facades/phoneNotifications.d.ts.map +1 -1
  65. package/build/facades/phoneNotifications.js +4 -14
  66. package/build/facades/phoneNotifications.js.map +1 -1
  67. package/build/facades/speech.d.ts +7 -6
  68. package/build/facades/speech.d.ts.map +1 -1
  69. package/build/facades/speech.js +1 -1
  70. package/build/facades/speech.js.map +1 -1
  71. package/build/generated/releaseMetadata.d.ts +12 -0
  72. package/build/generated/releaseMetadata.d.ts.map +1 -0
  73. package/build/generated/releaseMetadata.js +10 -0
  74. package/build/generated/releaseMetadata.js.map +1 -0
  75. package/build/index.d.ts +12 -10
  76. package/build/index.d.ts.map +1 -1
  77. package/build/index.js +7 -6
  78. package/build/index.js.map +1 -1
  79. package/build/react/MentraLiveOtaFlow.d.ts +44 -0
  80. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  81. package/build/react/MentraLiveOtaFlow.js +430 -0
  82. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  83. package/build/react/index.d.ts +3 -0
  84. package/build/react/index.d.ts.map +1 -0
  85. package/build/react/index.js +3 -0
  86. package/build/react/index.js.map +1 -0
  87. package/build/react/useEngineSnapshot.d.ts +2 -0
  88. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  89. package/build/react/useEngineSnapshot.js +14 -0
  90. package/build/react/useEngineSnapshot.js.map +1 -0
  91. package/build/react/useMentraLiveOta.d.ts +84 -0
  92. package/build/react/useMentraLiveOta.d.ts.map +1 -0
  93. package/build/react/useMentraLiveOta.js +627 -0
  94. package/build/react/useMentraLiveOta.js.map +1 -0
  95. package/build/runtime/bootstrap.d.ts +24 -1
  96. package/build/runtime/bootstrap.d.ts.map +1 -1
  97. package/build/runtime/bootstrap.js +17 -0
  98. package/build/runtime/bootstrap.js.map +1 -1
  99. package/build/runtime/scanQrSeam.d.ts +7 -0
  100. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  101. package/build/runtime/scanQrSeam.js +16 -0
  102. package/build/runtime/scanQrSeam.js.map +1 -0
  103. package/build/services/AppRegistry.d.ts +41 -57
  104. package/build/services/AppRegistry.d.ts.map +1 -1
  105. package/build/services/AppRegistry.js +208 -144
  106. package/build/services/AppRegistry.js.map +1 -1
  107. package/build/services/AudioCloudUplink.d.ts +12 -0
  108. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  109. package/build/services/AudioCloudUplink.js +22 -1
  110. package/build/services/AudioCloudUplink.js.map +1 -1
  111. package/build/services/AudioPlaybackService.d.ts +41 -2
  112. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  113. package/build/services/AudioPlaybackService.js +250 -33
  114. package/build/services/AudioPlaybackService.js.map +1 -1
  115. package/build/services/BlobStore.d.ts +4 -1
  116. package/build/services/BlobStore.d.ts.map +1 -1
  117. package/build/services/BlobStore.js +80 -19
  118. package/build/services/BlobStore.js.map +1 -1
  119. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  120. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  121. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  122. package/build/services/CloudClientService.d.ts +15 -0
  123. package/build/services/CloudClientService.d.ts.map +1 -1
  124. package/build/services/CloudClientService.js +93 -1
  125. package/build/services/CloudClientService.js.map +1 -1
  126. package/build/services/DeviceEventRouter.js +5 -5
  127. package/build/services/DeviceEventRouter.js.map +1 -1
  128. package/build/services/DisplayProcessor.d.ts +3 -3
  129. package/build/services/DisplayProcessor.js +3 -3
  130. package/build/services/DisplayProcessor.js.map +1 -1
  131. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  132. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  133. package/build/services/ForegroundLocationPermission.js +12 -0
  134. package/build/services/ForegroundLocationPermission.js.map +1 -0
  135. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  136. package/build/services/GlassesSettingsSync.js +9 -3
  137. package/build/services/GlassesSettingsSync.js.map +1 -1
  138. package/build/services/GlassesStatusProjection.d.ts +15 -1
  139. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  140. package/build/services/GlassesStatusProjection.js +18 -11
  141. package/build/services/GlassesStatusProjection.js.map +1 -1
  142. package/build/services/HotspotOtaTransport.d.ts +29 -0
  143. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  144. package/build/services/HotspotOtaTransport.js +147 -0
  145. package/build/services/HotspotOtaTransport.js.map +1 -0
  146. package/build/services/HotspotShutdown.d.ts +17 -0
  147. package/build/services/HotspotShutdown.d.ts.map +1 -0
  148. package/build/services/HotspotShutdown.js +29 -0
  149. package/build/services/HotspotShutdown.js.map +1 -0
  150. package/build/services/LocalDisplayManager.d.ts +17 -3
  151. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  152. package/build/services/LocalDisplayManager.js +108 -23
  153. package/build/services/LocalDisplayManager.js.map +1 -1
  154. package/build/services/LocalMiniappRuntime.d.ts +74 -2
  155. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  156. package/build/services/LocalMiniappRuntime.js +785 -291
  157. package/build/services/LocalMiniappRuntime.js.map +1 -1
  158. package/build/services/LocalMiniappStorage.d.ts +32 -0
  159. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  160. package/build/services/LocalMiniappStorage.js +66 -0
  161. package/build/services/LocalMiniappStorage.js.map +1 -0
  162. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  163. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  164. package/build/services/LocalMiniappUserIdentity.js +43 -0
  165. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  166. package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
  167. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  168. package/build/services/LocalSttFallbackCoordinator.js +18 -12
  169. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  170. package/build/services/MicStateCoordinator.d.ts +42 -1
  171. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  172. package/build/services/MicStateCoordinator.js +141 -3
  173. package/build/services/MicStateCoordinator.js.map +1 -1
  174. package/build/services/MiniappLauncher.d.ts.map +1 -1
  175. package/build/services/MiniappLauncher.js +23 -3
  176. package/build/services/MiniappLauncher.js.map +1 -1
  177. package/build/services/MiniappLiveness.d.ts +12 -0
  178. package/build/services/MiniappLiveness.d.ts.map +1 -0
  179. package/build/services/MiniappLiveness.js +16 -0
  180. package/build/services/MiniappLiveness.js.map +1 -0
  181. package/build/services/NativeHttpResponse.d.ts +3 -0
  182. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  183. package/build/services/NativeHttpResponse.js +6 -0
  184. package/build/services/NativeHttpResponse.js.map +1 -0
  185. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  186. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  187. package/build/services/OtaArtifactDownloader.js +226 -0
  188. package/build/services/OtaArtifactDownloader.js.map +1 -0
  189. package/build/services/OtaAutoChain.d.ts +41 -0
  190. package/build/services/OtaAutoChain.d.ts.map +1 -0
  191. package/build/services/OtaAutoChain.js +91 -0
  192. package/build/services/OtaAutoChain.js.map +1 -0
  193. package/build/services/OtaErrorMapping.d.ts +18 -0
  194. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  195. package/build/services/OtaErrorMapping.js +63 -0
  196. package/build/services/OtaErrorMapping.js.map +1 -0
  197. package/build/services/OtaInstallCoordinator.d.ts +120 -17
  198. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  199. package/build/services/OtaInstallCoordinator.js +605 -136
  200. package/build/services/OtaInstallCoordinator.js.map +1 -1
  201. package/build/services/OtaService.d.ts.map +1 -1
  202. package/build/services/OtaService.js +9 -2
  203. package/build/services/OtaService.js.map +1 -1
  204. package/build/services/OtaUpdateCheckService.d.ts +42 -4
  205. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  206. package/build/services/OtaUpdateCheckService.js +158 -26
  207. package/build/services/OtaUpdateCheckService.js.map +1 -1
  208. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  209. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  210. package/build/services/PhoneCalendarHelpers.js +157 -0
  211. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  212. package/build/services/PhoneCalendarService.d.ts +5 -0
  213. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  214. package/build/services/PhoneCalendarService.js +45 -0
  215. package/build/services/PhoneCalendarService.js.map +1 -0
  216. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  217. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  218. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  219. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  220. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  221. package/build/services/PhoneNotificationsSync.js +12 -10
  222. package/build/services/PhoneNotificationsSync.js.map +1 -1
  223. package/build/services/PhonePhotoCoordinator.d.ts +26 -2
  224. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  225. package/build/services/PhonePhotoCoordinator.js +80 -10
  226. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  227. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  228. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  229. package/build/services/PhoneStreamCoordinator.js +125 -13
  230. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  231. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  232. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  233. package/build/services/PhoneVideoCoordinator.js +10 -0
  234. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  235. package/build/services/SceneRenderer.d.ts.map +1 -1
  236. package/build/services/SceneRenderer.js +15 -0
  237. package/build/services/SceneRenderer.js.map +1 -1
  238. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  239. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  240. package/build/services/SentenceTtsPipeline.js +67 -0
  241. package/build/services/SentenceTtsPipeline.js.map +1 -0
  242. package/build/services/StreamLifecycleController.d.ts +3 -3
  243. package/build/services/StreamLifecycleController.js +3 -3
  244. package/build/services/StreamLifecycleController.js.map +1 -1
  245. package/build/services/SupportProfileSync.d.ts +22 -0
  246. package/build/services/SupportProfileSync.d.ts.map +1 -0
  247. package/build/services/SupportProfileSync.js +213 -0
  248. package/build/services/SupportProfileSync.js.map +1 -0
  249. package/build/services/TranscriptionRouting.d.ts +12 -0
  250. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  251. package/build/services/TranscriptionRouting.js +24 -0
  252. package/build/services/TranscriptionRouting.js.map +1 -0
  253. package/build/services/TtsTextSanitizer.d.ts +5 -0
  254. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  255. package/build/services/TtsTextSanitizer.js +61 -0
  256. package/build/services/TtsTextSanitizer.js.map +1 -0
  257. package/build/services/WifiAdbRequest.d.ts +17 -0
  258. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  259. package/build/services/WifiAdbRequest.js +35 -0
  260. package/build/services/WifiAdbRequest.js.map +1 -0
  261. package/build/services/asg/asgCameraApi.d.ts +43 -0
  262. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  263. package/build/services/asg/asgCameraApi.js +509 -26
  264. package/build/services/asg/asgCameraApi.js.map +1 -1
  265. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  266. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  267. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  268. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  269. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  270. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  271. package/build/services/asg/cameraRollExportLedger.js +78 -0
  272. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  273. package/build/services/asg/galleryNotices.d.ts +1 -1
  274. package/build/services/asg/galleryNotices.d.ts.map +1 -1
  275. package/build/services/asg/galleryNotices.js.map +1 -1
  276. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  277. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  278. package/build/services/asg/galleryPathMigration.js +26 -0
  279. package/build/services/asg/galleryPathMigration.js.map +1 -0
  280. package/build/services/asg/gallerySettingsService.d.ts +1 -0
  281. package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
  282. package/build/services/asg/gallerySettingsService.js +2 -0
  283. package/build/services/asg/gallerySettingsService.js.map +1 -1
  284. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  285. package/build/services/asg/gallerySyncService.js +162 -56
  286. package/build/services/asg/gallerySyncService.js.map +1 -1
  287. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  288. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  289. package/build/services/asg/galleryTransferLedger.js +225 -0
  290. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  291. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  292. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  293. package/build/services/asg/localNetworkTransport.js +145 -0
  294. package/build/services/asg/localNetworkTransport.js.map +1 -0
  295. package/build/services/asg/localStorageService.d.ts +18 -0
  296. package/build/services/asg/localStorageService.d.ts.map +1 -1
  297. package/build/services/asg/localStorageService.js +168 -19
  298. package/build/services/asg/localStorageService.js.map +1 -1
  299. package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
  300. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
  301. package/build/services/asg/mediaProcessingQueue.js +193 -62
  302. package/build/services/asg/mediaProcessingQueue.js.map +1 -1
  303. package/build/services/audioPlaybackAssets.d.ts +8 -0
  304. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  305. package/build/services/audioPlaybackAssets.js +7 -0
  306. package/build/services/audioPlaybackAssets.js.map +1 -0
  307. package/build/services/gallerySyncClock.js +1 -1
  308. package/build/services/gallerySyncClock.js.map +1 -1
  309. package/build/services/glassesClockSync.d.ts.map +1 -1
  310. package/build/services/glassesClockSync.js +7 -3
  311. package/build/services/glassesClockSync.js.map +1 -1
  312. package/build/services/manifestActions.d.ts +7 -0
  313. package/build/services/manifestActions.d.ts.map +1 -0
  314. package/build/services/manifestActions.js +25 -0
  315. package/build/services/manifestActions.js.map +1 -0
  316. package/build/services/otaDisplayState.d.ts +23 -12
  317. package/build/services/otaDisplayState.d.ts.map +1 -1
  318. package/build/services/otaDisplayState.js +36 -14
  319. package/build/services/otaDisplayState.js.map +1 -1
  320. package/build/services/otaInstallPolicy.d.ts +20 -4
  321. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  322. package/build/services/otaInstallPolicy.js +28 -3
  323. package/build/services/otaInstallPolicy.js.map +1 -1
  324. package/build/services/otaLegacyMapping.d.ts +1 -1
  325. package/build/services/otaLegacyMapping.d.ts.map +1 -1
  326. package/build/services/otaLegacyMapping.js.map +1 -1
  327. package/build/services/otaManifestPolicy.d.ts +14 -0
  328. package/build/services/otaManifestPolicy.d.ts.map +1 -0
  329. package/build/services/otaManifestPolicy.js +19 -0
  330. package/build/services/otaManifestPolicy.js.map +1 -0
  331. package/build/services/otaManifestUrl.d.ts +3 -0
  332. package/build/services/otaManifestUrl.d.ts.map +1 -0
  333. package/build/services/otaManifestUrl.js +38 -0
  334. package/build/services/otaManifestUrl.js.map +1 -0
  335. package/build/services/otaReleaseVersion.d.ts +10 -0
  336. package/build/services/otaReleaseVersion.d.ts.map +1 -0
  337. package/build/services/otaReleaseVersion.js +14 -0
  338. package/build/services/otaReleaseVersion.js.map +1 -0
  339. package/build/services/slimStreamStatus.d.ts +11 -0
  340. package/build/services/slimStreamStatus.d.ts.map +1 -1
  341. package/build/services/slimStreamStatus.js +14 -4
  342. package/build/services/slimStreamStatus.js.map +1 -1
  343. package/build/stores/appVisibility.d.ts +3 -0
  344. package/build/stores/appVisibility.d.ts.map +1 -0
  345. package/build/stores/appVisibility.js +3 -0
  346. package/build/stores/appVisibility.js.map +1 -0
  347. package/build/stores/apps.d.ts.map +1 -1
  348. package/build/stores/apps.js +18 -1
  349. package/build/stores/apps.js.map +1 -1
  350. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  351. package/build/stores/bluetoothSettingKeys.js +2 -0
  352. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  353. package/build/stores/core.d.ts +3 -3
  354. package/build/stores/core.d.ts.map +1 -1
  355. package/build/stores/core.js.map +1 -1
  356. package/build/stores/gallerySync.d.ts +2 -0
  357. package/build/stores/gallerySync.d.ts.map +1 -1
  358. package/build/stores/gallerySync.js +2 -0
  359. package/build/stores/gallerySync.js.map +1 -1
  360. package/build/stores/glasses.d.ts +10 -4
  361. package/build/stores/glasses.d.ts.map +1 -1
  362. package/build/stores/glasses.js +3 -0
  363. package/build/stores/glasses.js.map +1 -1
  364. package/build/stores/settings.d.ts +17 -0
  365. package/build/stores/settings.d.ts.map +1 -1
  366. package/build/stores/settings.js +157 -17
  367. package/build/stores/settings.js.map +1 -1
  368. package/build/types/applet.d.ts +3 -1
  369. package/build/types/applet.d.ts.map +1 -1
  370. package/build/types/applet.js +1 -1
  371. package/build/types/applet.js.map +1 -1
  372. package/build/types/asg.d.ts +7 -0
  373. package/build/types/asg.d.ts.map +1 -1
  374. package/build/types/asg.js.map +1 -1
  375. package/build/types/capabilities/even-realities-g1.d.ts.map +1 -1
  376. package/build/types/capabilities/even-realities-g1.js +2 -0
  377. package/build/types/capabilities/even-realities-g1.js.map +1 -1
  378. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  379. package/build/types/capabilities/even-realities-g2.js +2 -0
  380. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  381. package/build/types/capabilities/mentra-display.d.ts.map +1 -1
  382. package/build/types/capabilities/mentra-display.js +2 -0
  383. package/build/types/capabilities/mentra-display.js.map +1 -1
  384. package/build/types/capabilities/mentra-live.d.ts.map +1 -1
  385. package/build/types/capabilities/mentra-live.js +2 -0
  386. package/build/types/capabilities/mentra-live.js.map +1 -1
  387. package/build/types/capabilities/nimo.d.ts +9 -0
  388. package/build/types/capabilities/nimo.d.ts.map +1 -0
  389. package/build/types/capabilities/nimo.js +57 -0
  390. package/build/types/capabilities/nimo.js.map +1 -0
  391. package/build/types/capabilities/none.d.ts.map +1 -1
  392. package/build/types/capabilities/none.js +2 -0
  393. package/build/types/capabilities/none.js.map +1 -1
  394. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
  395. package/build/types/capabilities/simulated-glasses.js +2 -0
  396. package/build/types/capabilities/simulated-glasses.js.map +1 -1
  397. package/build/types/capabilities/vuzix-z100.d.ts.map +1 -1
  398. package/build/types/capabilities/vuzix-z100.js +2 -0
  399. package/build/types/capabilities/vuzix-z100.js.map +1 -1
  400. package/build/types/enums.d.ts +4 -26
  401. package/build/types/enums.d.ts.map +1 -1
  402. package/build/types/enums.js +3 -27
  403. package/build/types/enums.js.map +1 -1
  404. package/build/types/hardware.d.ts +6 -14
  405. package/build/types/hardware.d.ts.map +1 -1
  406. package/build/types/hardware.js +18 -4
  407. package/build/types/hardware.js.map +1 -1
  408. package/build/types/index.d.ts +3 -7
  409. package/build/types/index.d.ts.map +1 -1
  410. package/build/types/index.js +3 -7
  411. package/build/types/index.js.map +1 -1
  412. package/build/utils/configuredDevHost.d.ts +6 -0
  413. package/build/utils/configuredDevHost.d.ts.map +1 -0
  414. package/build/utils/configuredDevHost.js +19 -0
  415. package/build/utils/configuredDevHost.js.map +1 -0
  416. package/build/utils/devMiniappLaunch.d.ts +19 -8
  417. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  418. package/build/utils/devMiniappLaunch.js +144 -21
  419. package/build/utils/devMiniappLaunch.js.map +1 -1
  420. package/build/utils/diagnosticContext.d.ts.map +1 -1
  421. package/build/utils/diagnosticContext.js +15 -17
  422. package/build/utils/diagnosticContext.js.map +1 -1
  423. package/build/utils/display/composer/ColumnComposer.d.ts +1 -1
  424. package/build/utils/display/composer/ColumnComposer.js +1 -1
  425. package/build/utils/display/composer/ColumnComposer.js.map +1 -1
  426. package/build/utils/hardware/hardware.d.ts.map +1 -1
  427. package/build/utils/hardware/hardware.js +7 -3
  428. package/build/utils/hardware/hardware.js.map +1 -1
  429. package/build/utils/miniappDiagnostics.d.ts +64 -0
  430. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  431. package/build/utils/miniappDiagnostics.js +173 -0
  432. package/build/utils/miniappDiagnostics.js.map +1 -0
  433. package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
  434. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
  435. package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
  436. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
  437. package/build/utils/timers/timers.d.ts.map +1 -1
  438. package/build/utils/timers/timers.js +55 -18
  439. package/build/utils/timers/timers.js.map +1 -1
  440. package/package.json +66 -31
  441. package/src/assets/silence.wav +0 -0
  442. package/src/bluetooth-sdk/debug.ts +1 -0
  443. package/src/bluetooth-sdk/index.ts +2 -0
  444. package/src/bluetooth-sdk/ota-transport.ts +1 -0
  445. package/src/bluetooth-sdk/photo-receiver.ts +2 -0
  446. package/src/bluetooth-sdk/react.ts +1 -0
  447. package/src/bluetooth-sdk/types.ts +1 -0
  448. package/src/engine.ts +9 -4
  449. package/src/facades/dev.ts +17 -12
  450. package/src/facades/display.ts +1 -1
  451. package/src/facades/gallery.ts +1 -1
  452. package/src/facades/glasses.ts +20 -7
  453. package/src/facades/glassesSettings.ts +5 -0
  454. package/src/facades/miniapps.ts +7 -0
  455. package/src/facades/ota.ts +41 -13
  456. package/src/facades/pairing.ts +103 -23
  457. package/src/facades/permissions.ts +14 -0
  458. package/src/facades/phoneNotifications.ts +4 -13
  459. package/src/facades/speech.ts +21 -7
  460. package/src/generated/releaseMetadata.ts +20 -0
  461. package/src/index.ts +42 -13
  462. package/src/react/MentraLiveOtaFlow.tsx +754 -0
  463. package/src/react/index.ts +21 -0
  464. package/src/react/useEngineSnapshot.ts +16 -0
  465. package/src/react/useMentraLiveOta.ts +793 -0
  466. package/src/runtime/bootstrap.ts +33 -1
  467. package/src/runtime/scanQrSeam.ts +20 -0
  468. package/src/services/AppRegistry.ts +240 -149
  469. package/src/services/AudioCloudUplink.ts +23 -1
  470. package/src/services/AudioPlaybackService.ts +287 -38
  471. package/src/services/BlobStore.ts +79 -19
  472. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  473. package/src/services/CloudClientService.ts +96 -1
  474. package/src/services/DeviceEventRouter.ts +5 -5
  475. package/src/services/DisplayProcessor.ts +3 -3
  476. package/src/services/ForegroundLocationPermission.ts +24 -0
  477. package/src/services/GlassesSettingsSync.ts +9 -3
  478. package/src/services/GlassesStatusProjection.ts +20 -11
  479. package/src/services/HotspotOtaTransport.ts +185 -0
  480. package/src/services/HotspotShutdown.ts +41 -0
  481. package/src/services/LocalDisplayManager.ts +114 -24
  482. package/src/services/LocalMiniappRuntime.ts +967 -346
  483. package/src/services/LocalMiniappStorage.ts +82 -0
  484. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  485. package/src/services/LocalSttFallbackCoordinator.ts +19 -12
  486. package/src/services/MicStateCoordinator.ts +169 -4
  487. package/src/services/MiniappLauncher.ts +30 -3
  488. package/src/services/MiniappLiveness.ts +24 -0
  489. package/src/services/NativeHttpResponse.ts +6 -0
  490. package/src/services/OtaArtifactDownloader.ts +312 -0
  491. package/src/services/OtaAutoChain.ts +130 -0
  492. package/src/services/OtaErrorMapping.ts +80 -0
  493. package/src/services/OtaInstallCoordinator.ts +680 -151
  494. package/src/services/OtaService.ts +12 -7
  495. package/src/services/OtaUpdateCheckService.ts +205 -27
  496. package/src/services/PhoneCalendarHelpers.ts +212 -0
  497. package/src/services/PhoneCalendarService.ts +65 -0
  498. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  499. package/src/services/PhoneNotificationsSync.ts +12 -10
  500. package/src/services/PhonePhotoCoordinator.ts +117 -19
  501. package/src/services/PhoneStreamCoordinator.ts +139 -25
  502. package/src/services/PhoneVideoCoordinator.ts +11 -0
  503. package/src/services/SceneRenderer.ts +16 -0
  504. package/src/services/SentenceTtsPipeline.ts +106 -0
  505. package/src/services/StreamLifecycleController.ts +3 -3
  506. package/src/services/SupportProfileSync.ts +218 -0
  507. package/src/services/TranscriptionRouting.ts +37 -0
  508. package/src/services/TtsTextSanitizer.ts +66 -0
  509. package/src/services/WifiAdbRequest.ts +53 -0
  510. package/src/services/asg/asgCameraApi.ts +615 -33
  511. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  512. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  513. package/src/services/asg/galleryNotices.ts +1 -0
  514. package/src/services/asg/galleryPathMigration.ts +22 -0
  515. package/src/services/asg/gallerySettingsService.ts +3 -0
  516. package/src/services/asg/gallerySyncService.ts +184 -73
  517. package/src/services/asg/galleryTransferLedger.ts +312 -0
  518. package/src/services/asg/localNetworkTransport.ts +170 -0
  519. package/src/services/asg/localStorageService.ts +179 -24
  520. package/src/services/asg/mediaProcessingQueue.ts +209 -62
  521. package/src/services/audioPlaybackAssets.ts +8 -0
  522. package/src/services/gallerySyncClock.ts +1 -1
  523. package/src/services/glassesClockSync.ts +7 -3
  524. package/src/services/manifestActions.ts +30 -0
  525. package/src/services/otaDisplayState.ts +58 -17
  526. package/src/services/otaInstallPolicy.ts +34 -4
  527. package/src/services/otaLegacyMapping.ts +1 -1
  528. package/src/services/otaManifestPolicy.ts +42 -0
  529. package/src/services/otaManifestUrl.ts +44 -0
  530. package/src/services/otaReleaseVersion.ts +22 -0
  531. package/src/services/slimStreamStatus.ts +16 -5
  532. package/src/stores/appVisibility.ts +3 -0
  533. package/src/stores/apps.ts +19 -1
  534. package/src/stores/bluetoothSettingKeys.ts +2 -0
  535. package/src/stores/core.ts +4 -4
  536. package/src/stores/gallerySync.ts +4 -0
  537. package/src/stores/glasses.ts +16 -6
  538. package/src/stores/settings.ts +179 -18
  539. package/src/types/applet.ts +3 -1
  540. package/src/types/asg.ts +7 -0
  541. package/src/types/capabilities/even-realities-g1.ts +3 -0
  542. package/src/types/capabilities/even-realities-g2.ts +3 -0
  543. package/src/types/capabilities/mentra-display.ts +3 -0
  544. package/src/types/capabilities/mentra-live.ts +3 -0
  545. package/src/types/capabilities/nimo.ts +59 -0
  546. package/src/types/capabilities/none.ts +3 -0
  547. package/src/types/capabilities/simulated-glasses.ts +3 -0
  548. package/src/types/capabilities/vuzix-z100.ts +3 -0
  549. package/src/types/enums.ts +4 -28
  550. package/src/types/hardware.ts +23 -14
  551. package/src/types/index.ts +3 -6
  552. package/src/utils/configuredDevHost.ts +17 -0
  553. package/src/utils/devMiniappLaunch.ts +151 -23
  554. package/src/utils/diagnosticContext.ts +17 -17
  555. package/src/utils/display/composer/ColumnComposer.ts +1 -1
  556. package/src/utils/hardware/hardware.ts +7 -9
  557. package/src/utils/miniappDiagnostics.ts +226 -0
  558. package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
  559. package/src/utils/timers/timers.ts +57 -21
  560. package/build/devtools.d.ts +0 -11
  561. package/build/devtools.d.ts.map +0 -1
  562. package/build/devtools.js +0 -13
  563. package/build/devtools.js.map +0 -1
  564. package/build/internal.d.ts +0 -66
  565. package/build/internal.d.ts.map +0 -1
  566. package/build/internal.js +0 -89
  567. package/build/internal.js.map +0 -1
  568. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  569. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  570. package/build/services/asgOtaVersionUrl.js +0 -36
  571. package/build/services/asgOtaVersionUrl.js.map +0 -1
  572. package/src/devtools.ts +0 -13
  573. package/src/internal.ts +0 -158
  574. package/src/services/asgOtaVersionUrl.ts +0 -41
@@ -1 +1 @@
1
- {"version":3,"file":"BlobStore.js","sourceRoot":"","sources":["../../src/services/BlobStore.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * BlobStore\n *\n * Host-side implementation of `session.blob` — persistent, per-(userId,\n * packageName) BINARY storage for local miniapps, keyed like SimpleStorage (its\n * small-string sibling). Extracted from LocalMiniappRuntime the same way\n * NavigationHandlers is, to keep the runtime file small.\n *\n * Generic byte store — it knows nothing about any specific format. Highlights:\n * - chunked write/read (BLOB_CREATE/WRITE/COMMIT, BLOB_OPEN_READ/READ) so no\n * single bridge message is large;\n * - `setFromUrl` downloads a URL straight to disk (File.downloadFileAsync) and\n * `importFile` runs the OS picker (File.pickFileAsync) — both keep bytes\n * entirely host-side;\n * - `share` hands a stored file to the OS share sheet.\n *\n * Layout (mirrors SimpleStorage's scoping):\n * bytes: Paths.document/mentra_blobs/{userId}/{packageName}/{fileName}\n * metadata: MMKV key mentraos_blobmeta_{userId}_{packageName}_{key} → StoredBlobMeta JSON\n *\n * The on-disk file name is a generated id plus a mime-derived extension (iOS\n * AVPlayer keys a local file's format off the path extension, so blobs played\n * via `session.speaker.play` must carry one); the logical `key` (caller-chosen)\n * is the MMKV key. This decouples the filesystem from arbitrary caller keys.\n *\n * expo-file-system's new API is synchronous (create/writeBytes/md5/size), so\n * streaming chunk writes do no async work.\n */\n\nimport {Buffer} from \"buffer\"\nimport Share from \"react-native-share\"\nimport {Directory, File, Paths, type FileHandle} from \"expo-file-system\"\n\nimport {MiniappErrorCode} from \"@mentra/miniapp\"\nimport {storage as mmkvStorage} from \"../utils/storage/storage\"\nimport {sanitizeSegment, shareFileName, withDiskExt} from \"./blobPaths\"\n\nconst LOG_TAG = \"LocalMiniappRuntime\"\n\n/** Per-app blob quota: 1 GB. */\nexport const BLOB_QUOTA_BYTES = 1024 * 1024 * 1024\nconst ROOT_DIR_NAME = \"mentra_blobs\"\n/** Cache dir root holding short-lived, properly-named copies handed to the OS share sheet (one unique subdir per share). */\nconst SHARE_DIR_NAME = \"mentra_blob_share\"\nconst META_KEY_ROOT = \"mentraos_blobmeta_\"\n/** Cap md5 computation so we don't block the JS thread hashing a huge file. */\nconst MD5_MAX_BYTES = 50 * 1024 * 1024\n\n// Matches LocalMiniappRuntime.sendResult (see NavigationHandlers).\ntype SendResult = (\n packageName: string,\n requestId: string | undefined,\n ok: boolean,\n result?: unknown,\n error?: {code: MiniappErrorCode; message: string},\n) => void\n\nexport interface BlobStoreHooks {\n sendResult: SendResult\n /** Resolve the current user id (same source SimpleStorage uses). */\n getUserId: () => string\n}\n\ninterface StoredBlobMeta {\n key: string\n fileName: string\n name?: string\n mimeType: string\n bytes: number\n createdAt: number\n updatedAt: number\n md5?: string\n meta?: Record<string, string | number | boolean>\n}\n\ninterface ActiveUpload {\n packageName: string\n key: string\n fileName: string\n partFile: File\n handle: FileHandle\n bytes: number\n /** Bytes already committed under this key (overwrite target) — excluded from the quota check. */\n priorBytes: number\n name?: string\n mimeType: string\n meta?: Record<string, string | number | boolean>\n createdAt: number\n}\n\ninterface ActiveReader {\n packageName: string\n handle: FileHandle\n remaining: number\n}\n\nexport class BlobStore {\n private readonly uploads = new Map<string, ActiveUpload>() // key: `${pkg} ${key}`\n private readonly readers = new Map<string, ActiveReader>() // key: host handle id\n /** packageName → committed usage bytes, cached; invalidated on commit/delete/clear. */\n private readonly usageCache = new Map<string, number>()\n\n constructor(private readonly hooks: BlobStoreHooks) {}\n\n // ---- path / meta helpers -------------------------------------------------\n\n private dirFor(packageName: string): Directory {\n const userId = sanitizeSegment(this.hooks.getUserId())\n const dir = new Directory(Paths.document, ROOT_DIR_NAME, userId, sanitizeSegment(packageName))\n if (!dir.exists) dir.create({intermediates: true})\n return dir\n }\n\n private metaPrefix(packageName: string): string {\n return `${META_KEY_ROOT}${sanitizeSegment(this.hooks.getUserId())}_${packageName}_`\n }\n\n private metaKey(packageName: string, key: string): string {\n return this.metaPrefix(packageName) + key\n }\n\n private uploadKey(packageName: string, key: string): string {\n return `${packageName} ${key}`\n }\n\n private readMeta(packageName: string, key: string): StoredBlobMeta | null {\n const r = mmkvStorage.load<StoredBlobMeta>(this.metaKey(packageName, key))\n return r.is_ok() ? r.value : null\n }\n\n private writeMeta(packageName: string, meta: StoredBlobMeta): void {\n mmkvStorage.save(this.metaKey(packageName, meta.key), meta)\n }\n\n private allMeta(packageName: string): StoredBlobMeta[] {\n const prefix = this.metaPrefix(packageName)\n const out: StoredBlobMeta[] = []\n for (const k of mmkvStorage.getAllKeys()) {\n if (!k.startsWith(prefix)) continue\n const r = mmkvStorage.load<StoredBlobMeta>(k)\n if (r.is_ok() && r.value) out.push(r.value)\n }\n return out\n }\n\n private fileFor(packageName: string, fileName: string): File {\n return new File(this.dirFor(packageName), fileName)\n }\n\n /** Public API shape: stored meta + derived file:// uri. */\n private toBlobMeta(packageName: string, m: StoredBlobMeta) {\n return {\n key: m.key,\n name: m.name,\n mimeType: m.mimeType,\n bytes: m.bytes,\n createdAt: m.createdAt,\n updatedAt: m.updatedAt,\n md5: m.md5,\n uri: this.fileFor(packageName, m.fileName).uri,\n meta: m.meta,\n }\n }\n\n private committedUsage(packageName: string): number {\n const cached = this.usageCache.get(packageName)\n if (cached !== undefined) return cached\n let total = 0\n for (const m of this.allMeta(packageName)) total += m.bytes || 0\n this.usageCache.set(packageName, total)\n return total\n }\n\n private bumpUsage(packageName: string, delta: number): void {\n const cur = this.usageCache.get(packageName)\n if (cur !== undefined) this.usageCache.set(packageName, Math.max(0, cur + delta))\n }\n\n private safeMd5(file: File, bytes: number): string | undefined {\n if (bytes > MD5_MAX_BYTES) return undefined\n try {\n return file.md5 ?? undefined\n } catch {\n return undefined\n }\n }\n\n private makeId(): string {\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}${Math.random()\n .toString(36)\n .slice(2, 6)}`\n }\n\n /** Would storing `incoming` bytes under `key` exceed the per-app quota? */\n private overQuota(packageName: string, key: string, incoming: number): boolean {\n const priorBytes = this.readMeta(packageName, key)?.bytes ?? 0\n return this.committedUsage(packageName) - priorBytes + incoming > BLOB_QUOTA_BYTES\n }\n\n /** Publish a file already sitting at `fileName` as the blob for `key`; returns its public meta. */\n private commitFile(\n packageName: string,\n key: string,\n fileName: string,\n mimeType: string,\n name: string | undefined,\n extraMeta: Record<string, string | number | boolean> | undefined,\n ) {\n // Attach a mime-derived extension to the on-disk name. Consumers that key\n // format off the path — iOS AVPlayer under `session.speaker.play` — cannot\n // open an extension-less file, even though the bytes are valid.\n const named = withDiskExt(fileName, mimeType)\n if (named !== fileName) {\n try {\n this.fileFor(packageName, fileName).rename(named)\n fileName = named\n } catch {\n /* keep the extension-less name — the blob still stores and shares fine */\n }\n }\n const prior = this.readMeta(packageName, key)\n if (prior && prior.fileName !== fileName) {\n this.deleteFileQuiet(packageName, prior.fileName)\n this.bumpUsage(packageName, -(prior.bytes || 0))\n }\n const finalFile = this.fileFor(packageName, fileName)\n const bytes = finalFile.size ?? 0\n const now = Date.now()\n const meta: StoredBlobMeta = {\n key,\n fileName,\n name,\n mimeType,\n bytes,\n createdAt: prior?.createdAt ?? now,\n updatedAt: now,\n md5: this.safeMd5(finalFile, bytes),\n meta: extraMeta,\n }\n this.writeMeta(packageName, meta)\n this.bumpUsage(packageName, bytes)\n return this.toBlobMeta(packageName, meta)\n }\n\n // ---- streaming write -----------------------------------------------------\n\n handleCreate(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n try {\n const key = (typeof payload.key === \"string\" && payload.key) || this.makeId()\n const mapKey = this.uploadKey(packageName, key)\n const existing = this.uploads.get(mapKey)\n if (existing) this.discardUpload(existing)\n\n const fileName = this.makeId()\n const partFile = this.fileFor(packageName, fileName + \".part\")\n partFile.create({intermediates: true, overwrite: true})\n const handle = partFile.open()\n\n this.uploads.set(mapKey, {\n packageName,\n key,\n fileName,\n partFile,\n handle,\n bytes: 0,\n priorBytes: this.readMeta(packageName, key)?.bytes ?? 0,\n name: typeof payload.name === \"string\" ? payload.name : undefined,\n mimeType: typeof payload.mimeType === \"string\" ? payload.mimeType : \"application/octet-stream\",\n meta: (payload.meta as Record<string, string | number | boolean>) ?? undefined,\n createdAt: Date.now(),\n })\n this.hooks.sendResult(packageName, requestId, true, {key})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_WRITE_FAILED, err)\n }\n }\n\n handleWrite(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const up = this.uploads.get(this.uploadKey(packageName, key))\n if (!up) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_HANDLE_INVALID,\n message: `No open blob writer for key ${key}`,\n })\n return\n }\n try {\n const chunk = Buffer.from((payload.base64 as string) ?? \"\", \"base64\")\n const bytes = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)\n // A seek write (offset present) patches existing bytes in place — used to\n // rewrite a container header on finalize; it does not grow the blob.\n if (typeof payload.offset === \"number\") {\n if (payload.offset < 0 || payload.offset + bytes.length > up.bytes) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_WRITE_FAILED,\n message: \"writeAt offset out of range (must stay within written bytes)\",\n })\n return\n }\n up.handle.offset = payload.offset\n up.handle.writeBytes(bytes)\n up.handle.offset = up.bytes // restore append position\n this.hooks.sendResult(packageName, requestId, true, {bytesWritten: up.bytes})\n return\n }\n // Exclude the prior blob under this key — it's freed on commit (overwrite).\n if (this.committedUsage(packageName) - up.priorBytes + up.bytes + bytes.length > BLOB_QUOTA_BYTES) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_QUOTA_EXCEEDED,\n message: `Blob quota (${BLOB_QUOTA_BYTES} bytes) exceeded`,\n })\n return\n }\n up.handle.offset = up.bytes\n up.handle.writeBytes(bytes)\n up.bytes += bytes.length\n this.hooks.sendResult(packageName, requestId, true, {bytesWritten: up.bytes})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_WRITE_FAILED, err)\n }\n }\n\n handleCommit(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const mapKey = this.uploadKey(packageName, key)\n const up = this.uploads.get(mapKey)\n if (!up) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_HANDLE_INVALID,\n message: `No open blob writer for key ${key}`,\n })\n return\n }\n try {\n up.handle.close()\n up.partFile.rename(up.fileName) // drop \".part\"\n const extraMeta = {\n ...(up.meta ?? {}),\n ...((payload.meta as Record<string, string | number | boolean>) ?? {}),\n }\n const meta = this.commitFile(packageName, key, up.fileName, up.mimeType, up.name, extraMeta)\n this.uploads.delete(mapKey)\n this.hooks.sendResult(packageName, requestId, true, meta)\n } catch (err) {\n this.discardUpload(up)\n this.uploads.delete(mapKey)\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_WRITE_FAILED, err)\n }\n }\n\n handleAbort(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const mapKey = this.uploadKey(packageName, payload.key as string)\n const up = this.uploads.get(mapKey)\n if (up) {\n this.discardUpload(up)\n this.uploads.delete(mapKey)\n }\n this.hooks.sendResult(packageName, requestId, true)\n }\n\n // ---- download / import (host-side; no bytes cross the bridge) -------------\n\n async handleSetFromUrl(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n const key = payload.key as string\n const url = payload.url as string\n if (!key || !url) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, new Error(\"setFromUrl requires key + url\"))\n return\n }\n if (url.startsWith(\"file:\") || url.startsWith(\"javascript:\")) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_DOWNLOAD_FAILED,\n message: \"Unsupported URL scheme\",\n })\n return\n }\n const headers = payload.headers as Record<string, string> | undefined\n const fileName = this.makeId()\n const partFile = this.fileFor(packageName, fileName + \".part\")\n try {\n const dl = await File.downloadFileAsync(url, partFile, {idempotent: true, ...(headers ? {headers} : {})})\n const size = dl.size ?? 0\n if (this.overQuota(packageName, key, size)) {\n try {\n dl.delete()\n } catch {\n /* ignore */\n }\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_QUOTA_EXCEEDED,\n message: `Blob quota (${BLOB_QUOTA_BYTES} bytes) exceeded`,\n })\n return\n }\n partFile.rename(fileName)\n const mimeType =\n (payload.mimeType as string) || inferMime(basename(url)) || this.fileFor(packageName, fileName).type || OCTET\n const name = (payload.name as string) || basename(url) || key\n const meta = this.commitFile(\n packageName,\n key,\n fileName,\n mimeType,\n name,\n payload.meta as Record<string, string | number | boolean> | undefined,\n )\n this.hooks.sendResult(packageName, requestId, true, meta)\n } catch (err) {\n try {\n if (partFile.exists) partFile.delete()\n } catch {\n /* ignore */\n }\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_DOWNLOAD_FAILED, err)\n }\n }\n\n async handleImport(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n const key = (typeof payload.key === \"string\" && payload.key) || this.makeId()\n const mimeFilter = payload.mimeType as string | undefined\n\n let picked: File | File[] | null = null\n try {\n picked = await File.pickFileAsync(undefined, mimeFilter)\n } catch (err) {\n // Picker dismissed / cancelled (or unavailable) → resolve to null, not an error.\n console.log(`${LOG_TAG}: blob import picker dismissed`, err)\n this.hooks.sendResult(packageName, requestId, true, null)\n return\n }\n const file = Array.isArray(picked) ? picked[0] : picked\n if (!file) {\n this.hooks.sendResult(packageName, requestId, true, null)\n return\n }\n try {\n const size = file.size ?? 0\n if (this.overQuota(packageName, key, size)) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_QUOTA_EXCEEDED,\n message: `Blob quota (${BLOB_QUOTA_BYTES} bytes) exceeded`,\n })\n return\n }\n const fileName = this.makeId()\n file.copy(this.fileFor(packageName, fileName))\n const name = basename(file.uri) || key\n const mimeType = mimeFilter || file.type || inferMime(name) || OCTET\n const meta = this.commitFile(\n packageName,\n key,\n fileName,\n mimeType,\n name,\n payload.meta as Record<string, string | number | boolean> | undefined,\n )\n this.hooks.sendResult(packageName, requestId, true, meta)\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_IMPORT_FAILED, err)\n }\n }\n\n // ---- read ----------------------------------------------------------------\n\n handleGet(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const meta = this.readMeta(packageName, key)\n if (!meta || !this.fileFor(packageName, meta.fileName).exists) {\n if (meta) this.dropMeta(packageName, meta) // reconcile dangling meta\n this.hooks.sendResult(packageName, requestId, true, null)\n return\n }\n this.hooks.sendResult(packageName, requestId, true, this.toBlobMeta(packageName, meta))\n }\n\n handleList(packageName: string, _payload: Record<string, unknown>, requestId?: string): void {\n const blobs = this.allMeta(packageName)\n .filter((m) => this.fileFor(packageName, m.fileName).exists)\n .sort((a, b) => b.createdAt - a.createdAt)\n .map((m) => this.toBlobMeta(packageName, m))\n this.hooks.sendResult(packageName, requestId, true, {blobs})\n }\n\n handleUsage(packageName: string, _payload: Record<string, unknown>, requestId?: string): void {\n const metas = this.allMeta(packageName)\n this.hooks.sendResult(packageName, requestId, true, {\n bytes: metas.reduce((s, m) => s + (m.bytes || 0), 0),\n count: metas.length,\n quotaBytes: BLOB_QUOTA_BYTES,\n })\n }\n\n handleDelete(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const meta = this.readMeta(packageName, payload.key as string)\n if (meta) this.dropMeta(packageName, meta)\n this.hooks.sendResult(packageName, requestId, true)\n }\n\n handleClear(packageName: string, _payload: Record<string, unknown>, requestId?: string): void {\n try {\n // Abort any in-flight uploads / open readers first so nothing keeps writing\n // to a .part file in the directory we're about to delete.\n this.closeAppHandles(packageName)\n for (const m of this.allMeta(packageName)) mmkvStorage.remove(this.metaKey(packageName, m.key))\n const dir = this.dirFor(packageName)\n try {\n if (dir.exists) dir.delete()\n } catch {\n /* best-effort */\n }\n this.usageCache.set(packageName, 0)\n this.hooks.sendResult(packageName, requestId, true)\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)\n }\n }\n\n handleOpenRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const meta = this.readMeta(packageName, key)\n const file = meta ? this.fileFor(packageName, meta.fileName) : null\n if (!meta || !file || !file.exists) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_NOT_FOUND,\n message: `Blob ${key} not found`,\n })\n return\n }\n try {\n const handle = file.open()\n const handleId = `r_${this.makeId()}`\n this.readers.set(handleId, {packageName, handle, remaining: meta.bytes})\n this.hooks.sendResult(packageName, requestId, true, {handle: handleId, meta: this.toBlobMeta(packageName, meta)})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)\n }\n }\n\n handleRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const handleId = payload.handle as string\n const reader = this.readers.get(handleId)\n if (!reader || reader.packageName !== packageName) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_HANDLE_INVALID,\n message: \"Unknown blob read handle\",\n })\n return\n }\n try {\n const want = Math.max(0, Math.min(Number(payload.maxBytes) || 1024 * 1024, reader.remaining))\n const bytes = want > 0 ? reader.handle.readBytes(want) : new Uint8Array(0)\n reader.remaining -= bytes.length\n const done = reader.remaining <= 0\n const base64 = bytes.length\n ? Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString(\"base64\")\n : \"\"\n if (done) {\n try {\n reader.handle.close()\n } catch {\n /* ignore */\n }\n this.readers.delete(handleId)\n }\n this.hooks.sendResult(packageName, requestId, true, {base64, done})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)\n }\n }\n\n handleCloseRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const handleId = payload.handle as string\n const reader = this.readers.get(handleId)\n if (reader && reader.packageName === packageName) {\n try {\n reader.handle.close()\n } catch {\n /* ignore */\n }\n this.readers.delete(handleId)\n }\n this.hooks.sendResult(packageName, requestId, true)\n }\n\n // ---- share ---------------------------------------------------------------\n\n async handleShare(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n const key = payload.key as string\n const meta = this.readMeta(packageName, key)\n const file = meta ? this.fileFor(packageName, meta.fileName) : null\n if (!meta || !file || !file.exists) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_NOT_FOUND,\n message: `Blob ${key} not found`,\n })\n return\n }\n // The on-disk blob name is a generated id (mime extension attached at\n // commit; legacy blobs may lack it). react-native-share derives the shared\n // file's name + extension from the URL's path (its `filename` option only\n // applies to base64/data payloads, not file:// URLs), so sharing `file.uri`\n // directly would hand the recipient a machine-named file. Copy to a temp\n // file that carries the real display name + extension, share that, then\n // clean it up.\n const shareName = shareFileName(meta)\n // Copy into a per-share unique subdir so two concurrent shares that resolve\n // to the same display name can't clobber each other's temp file while\n // Share.open still references it. The file keeps `shareName` as its basename\n // so the OS share sheet shows the right name + extension.\n let tempDir: Directory | null = null\n try {\n tempDir = new Directory(Paths.cache, SHARE_DIR_NAME, this.makeId())\n tempDir.create({intermediates: true})\n const temp = new File(tempDir, shareName)\n file.copy(temp)\n await Share.open({\n url: temp.uri,\n type: meta.mimeType || OCTET,\n filename: shareName,\n })\n this.hooks.sendResult(packageName, requestId, true, {success: true})\n } catch (error: any) {\n if (error?.message?.includes(\"User did not share\")) {\n this.hooks.sendResult(packageName, requestId, true, {success: false, cancelled: true})\n } else {\n console.error(`${LOG_TAG}: blob share error:`, error)\n this.hooks.sendResult(packageName, requestId, true, {success: false})\n }\n } finally {\n if (tempDir) {\n try {\n if (tempDir.exists) tempDir.delete()\n } catch {\n /* ignore */\n }\n }\n }\n }\n\n // ---- lifecycle / cleanup -------------------------------------------------\n\n /** Called from LocalMiniappRuntime.unregisterApp — drop this app's in-flight state. */\n onAppGone(packageName: string): void {\n this.closeAppHandles(packageName)\n }\n\n /** Abort in-flight uploads + close open read handles for an app (no-op if none). */\n private closeAppHandles(packageName: string): void {\n for (const [k, up] of this.uploads) {\n if (up.packageName === packageName) {\n this.discardUpload(up)\n this.uploads.delete(k)\n }\n }\n for (const [k, reader] of this.readers) {\n if (reader.packageName === packageName) {\n try {\n reader.handle.close()\n } catch {\n /* ignore */\n }\n this.readers.delete(k)\n }\n }\n }\n\n private discardUpload(up: ActiveUpload): void {\n try {\n up.handle.close()\n } catch {\n /* ignore */\n }\n try {\n if (up.partFile.exists) up.partFile.delete()\n } catch {\n /* ignore */\n }\n }\n\n private dropMeta(packageName: string, meta: StoredBlobMeta): void {\n this.deleteFileQuiet(packageName, meta.fileName)\n mmkvStorage.remove(this.metaKey(packageName, meta.key))\n this.bumpUsage(packageName, -(meta.bytes || 0))\n }\n\n private deleteFileQuiet(packageName: string, fileName: string): void {\n try {\n const f = this.fileFor(packageName, fileName)\n if (f.exists) f.delete()\n } catch {\n /* ignore */\n }\n }\n\n private fail(packageName: string, requestId: string | undefined, code: MiniappErrorCode, err: unknown): void {\n console.error(`${LOG_TAG}: blob error [${code}]:`, err)\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code,\n message: err instanceof Error ? err.message : \"Blob error\",\n })\n }\n}\n\nconst OCTET = \"application/octet-stream\"\n\n/** Last path segment of a URL/URI, query stripped + percent-decoded. */\nfunction basename(uri: string): string {\n const noQuery = uri.split(\"?\")[0].split(\"#\")[0]\n const seg = noQuery.substring(noQuery.lastIndexOf(\"/\") + 1)\n try {\n return decodeURIComponent(seg)\n } catch {\n return seg\n }\n}\n\n/** Best-effort MIME from a filename extension. Returns undefined when unknown. */\nfunction inferMime(name: string): string | undefined {\n const dot = name.lastIndexOf(\".\")\n if (dot < 0) return undefined\n const ext = name.slice(dot + 1).toLowerCase()\n const map: Record<string, string> = {\n pdf: \"application/pdf\",\n epub: \"application/epub+zip\",\n zip: \"application/zip\",\n json: \"application/json\",\n txt: \"text/plain\",\n csv: \"text/csv\",\n html: \"text/html\",\n mp4: \"video/mp4\",\n mov: \"video/quicktime\",\n webm: \"video/webm\",\n mp3: \"audio/mpeg\",\n m4a: \"audio/mp4\",\n wav: \"audio/wav\",\n ogg: \"audio/ogg\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n }\n return map[ext]\n}\n"]}
1
+ {"version":3,"file":"BlobStore.js","sourceRoot":"","sources":["../../src/services/BlobStore.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * BlobStore\n *\n * Host-side implementation of `session.blob` — persistent, per-(userId,\n * packageName) BINARY storage for local miniapps, keyed like SimpleStorage (its\n * small-string sibling). Extracted from LocalMiniappRuntime the same way\n * NavigationHandlers is, to keep the runtime file small.\n *\n * Generic byte store — it knows nothing about any specific format. Highlights:\n * - chunked write/read (BLOB_CREATE/WRITE/COMMIT, BLOB_OPEN_READ/READ) so no\n * single bridge message is large;\n * - `setFromUrl` downloads a URL straight to disk (File.downloadFileAsync) and\n * `importFile` runs the OS picker (File.pickFileAsync) — both keep bytes\n * entirely host-side;\n * - `share` hands a stored file to the OS share sheet.\n *\n * Layout (mirrors SimpleStorage's scoping):\n * bytes: Paths.document/mentra_blobs/{userId}/{packageName}/{fileName}\n * metadata: MMKV key mentraos_blobmeta_{userId}_{packageName}_{key} → StoredBlobMeta JSON\n *\n * The on-disk file name is a generated id plus a mime-derived extension (iOS\n * AVPlayer keys a local file's format off the path extension, so blobs played\n * via `session.speaker.play` must carry one); the logical `key` (caller-chosen)\n * is the MMKV key. This decouples the filesystem from arbitrary caller keys.\n *\n * expo-file-system's new API is synchronous (create/writeBytes/md5/size), so\n * streaming chunk writes do no async work.\n */\n\nimport {Buffer} from \"buffer\"\nimport Share from \"react-native-share\"\nimport {Directory, File, Paths, type FileHandle} from \"expo-file-system\"\n\nimport {MiniappErrorCode} from \"@mentra/miniapp\"\nimport {storage as mmkvStorage} from \"../utils/storage/storage\"\nimport {sanitizeSegment, shareFileName, withDiskExt} from \"./blobPaths\"\n\nconst LOG_TAG = \"LocalMiniappRuntime\"\n\n/** Per-app blob quota: 1 GB. */\nexport const BLOB_QUOTA_BYTES = 1024 * 1024 * 1024\nconst ROOT_DIR_NAME = \"mentra_blobs\"\n/** Cache dir root holding short-lived, properly-named copies handed to the OS share sheet (one subdir per stored blob). */\nconst SHARE_DIR_NAME = \"mentra_blob_share\"\n/**\n * Keep prepared share handoffs alive long enough for recipient apps to read\n * them asynchronously (for example, an email composer attaching the file).\n * Stale copies are collected before the next share; the OS may evict cache\n * files sooner under storage pressure.\n */\nconst SHARE_CACHE_MAX_AGE_MS = 24 * 60 * 60 * 1000\nconst META_KEY_ROOT = \"mentraos_blobmeta_\"\n/** Cap md5 computation so we don't block the JS thread hashing a huge file. */\nconst MD5_MAX_BYTES = 50 * 1024 * 1024\n\n// Matches LocalMiniappRuntime.sendResult (see NavigationHandlers).\ntype SendResult = (\n packageName: string,\n requestId: string | undefined,\n ok: boolean,\n result?: unknown,\n error?: {code: MiniappErrorCode; message: string},\n) => void\n\nexport interface BlobStoreHooks {\n sendResult: SendResult\n /** Resolve the current user id (same source SimpleStorage uses). */\n getUserId: () => string\n}\n\ninterface StoredBlobMeta {\n key: string\n fileName: string\n name?: string\n mimeType: string\n bytes: number\n createdAt: number\n updatedAt: number\n md5?: string\n meta?: Record<string, string | number | boolean>\n}\n\ninterface ActiveUpload {\n packageName: string\n key: string\n fileName: string\n partFile: File\n handle: FileHandle\n bytes: number\n /** Bytes already committed under this key (overwrite target) — excluded from the quota check. */\n priorBytes: number\n name?: string\n mimeType: string\n meta?: Record<string, string | number | boolean>\n createdAt: number\n}\n\ninterface ActiveReader {\n packageName: string\n handle: FileHandle\n remaining: number\n}\n\nexport class BlobStore {\n private readonly uploads = new Map<string, ActiveUpload>() // key: `${pkg} ${key}`\n private readonly readers = new Map<string, ActiveReader>() // key: host handle id\n /** user + package → committed usage bytes, cached; invalidated on commit/delete/clear. */\n private readonly usageCache = new Map<string, number>()\n\n constructor(private readonly hooks: BlobStoreHooks) {}\n\n // ---- path / meta helpers -------------------------------------------------\n\n private currentIdentity(packageName: string): {userId: string; scope: string} {\n const userId = this.hooks.getUserId().trim()\n if (!userId) throw new Error(\"Mentra user identity is unavailable\")\n const scope = `${userId}\\0${packageName}`\n return {userId, scope}\n }\n\n private dirFor(packageName: string): Directory {\n const dir = new Directory(\n Paths.document,\n ROOT_DIR_NAME,\n sanitizeSegment(this.currentIdentity(packageName).userId),\n sanitizeSegment(packageName),\n )\n if (!dir.exists) dir.create({intermediates: true})\n return dir\n }\n\n private metaPrefix(packageName: string): string {\n return `${META_KEY_ROOT}${sanitizeSegment(this.currentIdentity(packageName).userId)}_${packageName}_`\n }\n\n private metaKey(packageName: string, key: string): string {\n return this.metaPrefix(packageName) + key\n }\n\n private uploadKey(packageName: string, key: string): string {\n return `${packageName} ${key}`\n }\n\n private readMeta(packageName: string, key: string): StoredBlobMeta | null {\n const r = mmkvStorage.load<StoredBlobMeta>(this.metaKey(packageName, key))\n return r.is_ok() ? r.value : null\n }\n\n private writeMeta(packageName: string, meta: StoredBlobMeta): void {\n mmkvStorage.save(this.metaKey(packageName, meta.key), meta)\n }\n\n private allMeta(packageName: string): StoredBlobMeta[] {\n const prefix = this.metaPrefix(packageName)\n const out: StoredBlobMeta[] = []\n for (const k of mmkvStorage.getAllKeys()) {\n if (!k.startsWith(prefix)) continue\n const r = mmkvStorage.load<StoredBlobMeta>(k)\n if (r.is_ok() && r.value) out.push(r.value)\n }\n return out\n }\n\n private fileFor(packageName: string, fileName: string): File {\n return new File(this.dirFor(packageName), fileName)\n }\n\n /** Public API shape: stored meta + derived file:// uri. */\n private toBlobMeta(packageName: string, m: StoredBlobMeta) {\n return {\n key: m.key,\n name: m.name,\n mimeType: m.mimeType,\n bytes: m.bytes,\n createdAt: m.createdAt,\n updatedAt: m.updatedAt,\n md5: m.md5,\n uri: this.fileFor(packageName, m.fileName).uri,\n meta: m.meta,\n }\n }\n\n private committedUsage(packageName: string): number {\n const {scope} = this.currentIdentity(packageName)\n const cached = this.usageCache.get(scope)\n if (cached !== undefined) return cached\n let total = 0\n for (const m of this.allMeta(packageName)) total += m.bytes || 0\n this.usageCache.set(scope, total)\n return total\n }\n\n private bumpUsage(packageName: string, delta: number): void {\n const {scope} = this.currentIdentity(packageName)\n const cur = this.usageCache.get(scope)\n if (cur !== undefined) this.usageCache.set(scope, Math.max(0, cur + delta))\n }\n\n private safeMd5(file: File, bytes: number): string | undefined {\n if (bytes > MD5_MAX_BYTES) return undefined\n try {\n return file.md5 ?? undefined\n } catch {\n return undefined\n }\n }\n\n private makeId(): string {\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}${Math.random()\n .toString(36)\n .slice(2, 6)}`\n }\n\n /** Would storing `incoming` bytes under `key` exceed the per-app quota? */\n private overQuota(packageName: string, key: string, incoming: number): boolean {\n const priorBytes = this.readMeta(packageName, key)?.bytes ?? 0\n return this.committedUsage(packageName) - priorBytes + incoming > BLOB_QUOTA_BYTES\n }\n\n /** Publish a file already sitting at `fileName` as the blob for `key`; returns its public meta. */\n private commitFile(\n packageName: string,\n key: string,\n fileName: string,\n mimeType: string,\n name: string | undefined,\n extraMeta: Record<string, string | number | boolean> | undefined,\n ) {\n // Attach a mime-derived extension to the on-disk name. Consumers that key\n // format off the path — iOS AVPlayer under `session.speaker.play` — cannot\n // open an extension-less file, even though the bytes are valid.\n const named = withDiskExt(fileName, mimeType)\n if (named !== fileName) {\n try {\n this.fileFor(packageName, fileName).rename(named)\n fileName = named\n } catch {\n /* keep the extension-less name — the blob still stores and shares fine */\n }\n }\n const prior = this.readMeta(packageName, key)\n if (prior && prior.fileName !== fileName) {\n this.deleteFileQuiet(packageName, prior.fileName)\n this.bumpUsage(packageName, -(prior.bytes || 0))\n }\n const finalFile = this.fileFor(packageName, fileName)\n const bytes = finalFile.size ?? 0\n const now = Date.now()\n const meta: StoredBlobMeta = {\n key,\n fileName,\n name,\n mimeType,\n bytes,\n createdAt: prior?.createdAt ?? now,\n updatedAt: now,\n md5: this.safeMd5(finalFile, bytes),\n meta: extraMeta,\n }\n this.writeMeta(packageName, meta)\n this.bumpUsage(packageName, bytes)\n return this.toBlobMeta(packageName, meta)\n }\n\n // ---- streaming write -----------------------------------------------------\n\n handleCreate(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n try {\n const key = (typeof payload.key === \"string\" && payload.key) || this.makeId()\n const mapKey = this.uploadKey(packageName, key)\n const existing = this.uploads.get(mapKey)\n if (existing) this.discardUpload(existing)\n\n const fileName = this.makeId()\n const partFile = this.fileFor(packageName, fileName + \".part\")\n partFile.create({intermediates: true, overwrite: true})\n const handle = partFile.open()\n\n this.uploads.set(mapKey, {\n packageName,\n key,\n fileName,\n partFile,\n handle,\n bytes: 0,\n priorBytes: this.readMeta(packageName, key)?.bytes ?? 0,\n name: typeof payload.name === \"string\" ? payload.name : undefined,\n mimeType: typeof payload.mimeType === \"string\" ? payload.mimeType : \"application/octet-stream\",\n meta: (payload.meta as Record<string, string | number | boolean>) ?? undefined,\n createdAt: Date.now(),\n })\n this.hooks.sendResult(packageName, requestId, true, {key})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_WRITE_FAILED, err)\n }\n }\n\n handleWrite(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const up = this.uploads.get(this.uploadKey(packageName, key))\n if (!up) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_HANDLE_INVALID,\n message: `No open blob writer for key ${key}`,\n })\n return\n }\n try {\n const chunk = Buffer.from((payload.base64 as string) ?? \"\", \"base64\")\n const bytes = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength)\n // A seek write (offset present) patches existing bytes in place — used to\n // rewrite a container header on finalize; it does not grow the blob.\n if (typeof payload.offset === \"number\") {\n if (payload.offset < 0 || payload.offset + bytes.length > up.bytes) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_WRITE_FAILED,\n message: \"writeAt offset out of range (must stay within written bytes)\",\n })\n return\n }\n up.handle.offset = payload.offset\n up.handle.writeBytes(bytes)\n up.handle.offset = up.bytes // restore append position\n this.hooks.sendResult(packageName, requestId, true, {bytesWritten: up.bytes})\n return\n }\n // Exclude the prior blob under this key — it's freed on commit (overwrite).\n if (this.committedUsage(packageName) - up.priorBytes + up.bytes + bytes.length > BLOB_QUOTA_BYTES) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_QUOTA_EXCEEDED,\n message: `Blob quota (${BLOB_QUOTA_BYTES} bytes) exceeded`,\n })\n return\n }\n up.handle.offset = up.bytes\n up.handle.writeBytes(bytes)\n up.bytes += bytes.length\n this.hooks.sendResult(packageName, requestId, true, {bytesWritten: up.bytes})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_WRITE_FAILED, err)\n }\n }\n\n handleCommit(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const mapKey = this.uploadKey(packageName, key)\n const up = this.uploads.get(mapKey)\n if (!up) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_HANDLE_INVALID,\n message: `No open blob writer for key ${key}`,\n })\n return\n }\n try {\n up.handle.close()\n up.partFile.rename(up.fileName) // drop \".part\"\n const extraMeta = {\n ...(up.meta ?? {}),\n ...((payload.meta as Record<string, string | number | boolean>) ?? {}),\n }\n const meta = this.commitFile(packageName, key, up.fileName, up.mimeType, up.name, extraMeta)\n this.uploads.delete(mapKey)\n this.hooks.sendResult(packageName, requestId, true, meta)\n } catch (err) {\n this.discardUpload(up)\n this.uploads.delete(mapKey)\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_WRITE_FAILED, err)\n }\n }\n\n handleAbort(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const mapKey = this.uploadKey(packageName, payload.key as string)\n const up = this.uploads.get(mapKey)\n if (up) {\n this.discardUpload(up)\n this.uploads.delete(mapKey)\n }\n this.hooks.sendResult(packageName, requestId, true)\n }\n\n // ---- download / import (host-side; no bytes cross the bridge) -------------\n\n async handleSetFromUrl(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n const key = payload.key as string\n const url = payload.url as string\n if (!key || !url) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, new Error(\"setFromUrl requires key + url\"))\n return\n }\n if (url.startsWith(\"file:\") || url.startsWith(\"javascript:\")) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_DOWNLOAD_FAILED,\n message: \"Unsupported URL scheme\",\n })\n return\n }\n const headers = payload.headers as Record<string, string> | undefined\n const fileName = this.makeId()\n const partFile = this.fileFor(packageName, fileName + \".part\")\n try {\n const dl = await File.downloadFileAsync(url, partFile, {idempotent: true, ...(headers ? {headers} : {})})\n const size = dl.size ?? 0\n if (this.overQuota(packageName, key, size)) {\n try {\n dl.delete()\n } catch {\n /* ignore */\n }\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_QUOTA_EXCEEDED,\n message: `Blob quota (${BLOB_QUOTA_BYTES} bytes) exceeded`,\n })\n return\n }\n partFile.rename(fileName)\n const mimeType =\n (payload.mimeType as string) || inferMime(basename(url)) || this.fileFor(packageName, fileName).type || OCTET\n const name = (payload.name as string) || basename(url) || key\n const meta = this.commitFile(\n packageName,\n key,\n fileName,\n mimeType,\n name,\n payload.meta as Record<string, string | number | boolean> | undefined,\n )\n this.hooks.sendResult(packageName, requestId, true, meta)\n } catch (err) {\n try {\n if (partFile.exists) partFile.delete()\n } catch {\n /* ignore */\n }\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_DOWNLOAD_FAILED, err)\n }\n }\n\n async handleImport(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n const key = (typeof payload.key === \"string\" && payload.key) || this.makeId()\n const mimeFilter = payload.mimeType as string | undefined\n\n let picked: File | File[] | null = null\n try {\n picked = await File.pickFileAsync(undefined, mimeFilter)\n } catch (err) {\n // Picker dismissed / cancelled (or unavailable) → resolve to null, not an error.\n console.log(`${LOG_TAG}: blob import picker dismissed`, err)\n this.hooks.sendResult(packageName, requestId, true, null)\n return\n }\n const file = Array.isArray(picked) ? picked[0] : picked\n if (!file) {\n this.hooks.sendResult(packageName, requestId, true, null)\n return\n }\n try {\n const size = file.size ?? 0\n if (this.overQuota(packageName, key, size)) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_QUOTA_EXCEEDED,\n message: `Blob quota (${BLOB_QUOTA_BYTES} bytes) exceeded`,\n })\n return\n }\n const fileName = this.makeId()\n file.copy(this.fileFor(packageName, fileName))\n const name = basename(file.uri) || key\n const mimeType = mimeFilter || file.type || inferMime(name) || OCTET\n const meta = this.commitFile(\n packageName,\n key,\n fileName,\n mimeType,\n name,\n payload.meta as Record<string, string | number | boolean> | undefined,\n )\n this.hooks.sendResult(packageName, requestId, true, meta)\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.BLOB_IMPORT_FAILED, err)\n }\n }\n\n // ---- read ----------------------------------------------------------------\n\n handleGet(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const meta = this.readMeta(packageName, key)\n if (!meta || !this.fileFor(packageName, meta.fileName).exists) {\n if (meta) this.dropMeta(packageName, meta) // reconcile dangling meta\n this.hooks.sendResult(packageName, requestId, true, null)\n return\n }\n this.hooks.sendResult(packageName, requestId, true, this.toBlobMeta(packageName, meta))\n }\n\n handleList(packageName: string, _payload: Record<string, unknown>, requestId?: string): void {\n const blobs = this.allMeta(packageName)\n .filter((m) => this.fileFor(packageName, m.fileName).exists)\n .sort((a, b) => b.createdAt - a.createdAt)\n .map((m) => this.toBlobMeta(packageName, m))\n this.hooks.sendResult(packageName, requestId, true, {blobs})\n }\n\n handleUsage(packageName: string, _payload: Record<string, unknown>, requestId?: string): void {\n const metas = this.allMeta(packageName)\n this.hooks.sendResult(packageName, requestId, true, {\n bytes: metas.reduce((s, m) => s + (m.bytes || 0), 0),\n count: metas.length,\n quotaBytes: BLOB_QUOTA_BYTES,\n })\n }\n\n handleDelete(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const meta = this.readMeta(packageName, payload.key as string)\n if (meta) this.dropMeta(packageName, meta)\n this.hooks.sendResult(packageName, requestId, true)\n }\n\n handleClear(packageName: string, _payload: Record<string, unknown>, requestId?: string): void {\n try {\n // Abort any in-flight uploads / open readers first so nothing keeps writing\n // to a .part file in the directory we're about to delete.\n this.closeAppHandles(packageName)\n for (const m of this.allMeta(packageName)) mmkvStorage.remove(this.metaKey(packageName, m.key))\n const dir = this.dirFor(packageName)\n try {\n if (dir.exists) dir.delete()\n } catch {\n /* best-effort */\n }\n this.usageCache.set(this.currentIdentity(packageName).scope, 0)\n this.hooks.sendResult(packageName, requestId, true)\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)\n }\n }\n\n handleOpenRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const key = payload.key as string\n const meta = this.readMeta(packageName, key)\n const file = meta ? this.fileFor(packageName, meta.fileName) : null\n if (!meta || !file || !file.exists) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_NOT_FOUND,\n message: `Blob ${key} not found`,\n })\n return\n }\n try {\n const handle = file.open()\n const handleId = `r_${this.makeId()}`\n this.readers.set(handleId, {packageName, handle, remaining: meta.bytes})\n this.hooks.sendResult(packageName, requestId, true, {handle: handleId, meta: this.toBlobMeta(packageName, meta)})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)\n }\n }\n\n handleRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const handleId = payload.handle as string\n const reader = this.readers.get(handleId)\n if (!reader || reader.packageName !== packageName) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_HANDLE_INVALID,\n message: \"Unknown blob read handle\",\n })\n return\n }\n try {\n const want = Math.max(0, Math.min(Number(payload.maxBytes) || 1024 * 1024, reader.remaining))\n const bytes = want > 0 ? reader.handle.readBytes(want) : new Uint8Array(0)\n reader.remaining -= bytes.length\n const done = reader.remaining <= 0\n const base64 = bytes.length\n ? Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString(\"base64\")\n : \"\"\n if (done) {\n try {\n reader.handle.close()\n } catch {\n /* ignore */\n }\n this.readers.delete(handleId)\n }\n this.hooks.sendResult(packageName, requestId, true, {base64, done})\n } catch (err) {\n this.fail(packageName, requestId, MiniappErrorCode.INTERNAL, err)\n }\n }\n\n handleCloseRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void {\n const handleId = payload.handle as string\n const reader = this.readers.get(handleId)\n if (reader && reader.packageName === packageName) {\n try {\n reader.handle.close()\n } catch {\n /* ignore */\n }\n this.readers.delete(handleId)\n }\n this.hooks.sendResult(packageName, requestId, true)\n }\n\n // ---- share ---------------------------------------------------------------\n\n /** Best-effort GC for prepared share handoffs retained in the OS cache. */\n private cleanupShareCache(now = Date.now()): void {\n try {\n const root = new Directory(Paths.cache, SHARE_DIR_NAME)\n if (!root.exists) return\n const cutoff = now - SHARE_CACHE_MAX_AGE_MS\n for (const entry of root.list()) {\n if (!(entry instanceof Directory)) continue\n try {\n const info = entry.info()\n // modificationTime is available on both platforms; creationTime can\n // be absent on Android versions before API 26. The directory id\n // begins with Date.now().toString(36), which is a final fallback.\n const encoded = entry.name.split(\"-\", 1)[0]\n const encodedTime = /^[0-9a-z]+$/.test(encoded) ? Number.parseInt(encoded, 36) : Number.NaN\n const timestamp = info.modificationTime ?? info.creationTime ?? encodedTime\n if (Number.isFinite(timestamp) && timestamp < cutoff) entry.delete()\n } catch {\n // Keep scanning if one cache entry disappears or is unreadable.\n }\n }\n } catch {\n // Cache cleanup must never prevent a share.\n }\n }\n\n async handleShare(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n const key = payload.key as string\n const meta = this.readMeta(packageName, key)\n const file = meta ? this.fileFor(packageName, meta.fileName) : null\n if (!meta || !file || !file.exists) {\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.BLOB_NOT_FOUND,\n message: `Blob ${key} not found`,\n })\n return\n }\n // The on-disk blob name is a generated id (mime extension attached at\n // commit; legacy blobs may lack it). react-native-share derives the shared\n // file's name + extension from the URL's path (its `filename` option only\n // applies to base64/data payloads, not file:// URLs), so sharing `file.uri`\n // directly would hand the recipient a machine-named file. Copy to a temp\n // file that carries the real display name + extension, share that, then\n // clean it up after the recipient has had time to consume it.\n const shareName = shareFileName(meta)\n // Key the cache directory by the immutable stored filename. Repeated or\n // concurrent shares of the same blob can safely reference the same bytes,\n // avoiding an extra full-sized cache copy for every share. Different blobs\n // still get isolated directories even when they use the same display name.\n // The file keeps `shareName` as its basename so the OS share sheet shows the\n // right name + extension.\n let tempDir: Directory | null = null\n let cacheReady = false\n try {\n this.cleanupShareCache()\n tempDir = new Directory(Paths.cache, SHARE_DIR_NAME, sanitizeSegment(meta.fileName))\n if (!tempDir.exists) tempDir.create({intermediates: true})\n const temp = new File(tempDir, shareName)\n if (!temp.exists || temp.size !== meta.bytes) {\n if (temp.exists) temp.delete()\n file.copy(temp)\n }\n cacheReady = true\n await Share.open({\n url: temp.uri,\n type: meta.mimeType || OCTET,\n filename: shareName,\n })\n // Share.open resolves once the OS accepts the handoff. Recipient apps may\n // still read the URI asynchronously, so retain this cache copy for GC.\n this.hooks.sendResult(packageName, requestId, true, {success: true})\n } catch (error: any) {\n if (error?.message?.includes(\"User did not share\")) {\n this.hooks.sendResult(packageName, requestId, true, {success: false, cancelled: true})\n } else {\n console.error(`${LOG_TAG}: blob share error:`, error)\n this.hooks.sendResult(packageName, requestId, true, {success: false})\n }\n } finally {\n // Once a reusable cache entry is ready, retain it even if this particular\n // sheet is cancelled or fails: another concurrent/recent share may still\n // be reading the same file. Only remove an entry whose preparation did\n // not finish; ready entries are collected after the retention window.\n if (tempDir && !cacheReady) {\n try {\n if (tempDir.exists) tempDir.delete()\n } catch {\n /* ignore */\n }\n }\n }\n }\n\n // ---- lifecycle / cleanup -------------------------------------------------\n\n /** Called from LocalMiniappRuntime.unregisterApp — drop this app's in-flight state. */\n onAppGone(packageName: string): void {\n this.closeAppHandles(packageName)\n }\n\n /** Abort in-flight uploads + close open read handles for an app (no-op if none). */\n private closeAppHandles(packageName: string): void {\n for (const [k, up] of this.uploads) {\n if (up.packageName === packageName) {\n this.discardUpload(up)\n this.uploads.delete(k)\n }\n }\n for (const [k, reader] of this.readers) {\n if (reader.packageName === packageName) {\n try {\n reader.handle.close()\n } catch {\n /* ignore */\n }\n this.readers.delete(k)\n }\n }\n }\n\n private discardUpload(up: ActiveUpload): void {\n try {\n up.handle.close()\n } catch {\n /* ignore */\n }\n try {\n if (up.partFile.exists) up.partFile.delete()\n } catch {\n /* ignore */\n }\n }\n\n private dropMeta(packageName: string, meta: StoredBlobMeta): void {\n this.deleteFileQuiet(packageName, meta.fileName)\n mmkvStorage.remove(this.metaKey(packageName, meta.key))\n this.bumpUsage(packageName, -(meta.bytes || 0))\n }\n\n private deleteFileQuiet(packageName: string, fileName: string): void {\n try {\n const f = this.fileFor(packageName, fileName)\n if (f.exists) f.delete()\n } catch {\n /* ignore */\n }\n }\n\n private fail(packageName: string, requestId: string | undefined, code: MiniappErrorCode, err: unknown): void {\n console.error(`${LOG_TAG}: blob error [${code}]:`, err)\n this.hooks.sendResult(packageName, requestId, false, undefined, {\n code,\n message: err instanceof Error ? err.message : \"Blob error\",\n })\n }\n}\n\nconst OCTET = \"application/octet-stream\"\n\n/** Last path segment of a URL/URI, query stripped + percent-decoded. */\nfunction basename(uri: string): string {\n const noQuery = uri.split(\"?\")[0].split(\"#\")[0]\n const seg = noQuery.substring(noQuery.lastIndexOf(\"/\") + 1)\n try {\n return decodeURIComponent(seg)\n } catch {\n return seg\n }\n}\n\n/** Best-effort MIME from a filename extension. Returns undefined when unknown. */\nfunction inferMime(name: string): string | undefined {\n const dot = name.lastIndexOf(\".\")\n if (dot < 0) return undefined\n const ext = name.slice(dot + 1).toLowerCase()\n const map: Record<string, string> = {\n pdf: \"application/pdf\",\n epub: \"application/epub+zip\",\n zip: \"application/zip\",\n json: \"application/json\",\n txt: \"text/plain\",\n csv: \"text/csv\",\n html: \"text/html\",\n mp4: \"video/mp4\",\n mov: \"video/quicktime\",\n webm: \"video/webm\",\n mp3: \"audio/mpeg\",\n m4a: \"audio/mp4\",\n wav: \"audio/wav\",\n ogg: \"audio/ogg\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n }\n return map[ext]\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"CloudAudioSubscriptionSync.d.ts","sourceRoot":"","sources":["../../src/services/CloudAudioSubscriptionSync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAK;IAEhB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQ/B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAKjC"}
1
+ {"version":3,"file":"CloudAudioSubscriptionSync.d.ts","sourceRoot":"","sources":["../../src/services/CloudAudioSubscriptionSync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,UAAU,CAAK;IAEhB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAoB/B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAO5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAKjC"}
@@ -18,7 +18,19 @@ export class CloudAudioSubscriptionSync {
18
18
  lastAppliedKey = "";
19
19
  pendingKey = "";
20
20
  begin(nextKey) {
21
- if (nextKey === this.lastAppliedKey || nextKey === this.pendingKey) {
21
+ // Exact duplicate of the write already in flight — nothing to do.
22
+ if (nextKey === this.pendingKey) {
23
+ return false;
24
+ }
25
+ // Matches the last successfully applied set, but ONLY skip when nothing
26
+ // else is in flight. If a different write is pending (e.g. desired went
27
+ // fr-FR -> [] -> fr-FR while the [] write is still on the wire),
28
+ // lastAppliedKey is stale: it names what was applied BEFORE the in-flight
29
+ // write lands. Skipping here would drop the re-subscribe and strand the
30
+ // cloud on the intermediate (empty) set — captions silently die on any
31
+ // rapid A -> B -> A subscription churn. The cloud's own version counter
32
+ // resolves ordering between the concurrent writes, so sending both is safe.
33
+ if (nextKey === this.lastAppliedKey && this.pendingKey === "") {
22
34
  return false;
23
35
  }
24
36
  this.pendingKey = nextKey;
@@ -1 +1 @@
1
- {"version":3,"file":"CloudAudioSubscriptionSync.js","sourceRoot":"","sources":["../../src/services/CloudAudioSubscriptionSync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,0BAA0B;IAC7B,cAAc,GAAG,EAAE,CAAA;IACnB,UAAU,GAAG,EAAE,CAAA;IAEhB,KAAK,CAAC,OAAe;QAC1B,IAAI,OAAO,KAAK,IAAI,CAAC,cAAc,IAAI,OAAO,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YACnE,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAEM,SAAS,CAAC,GAAW;QAC1B,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACtB,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,GAAG,CAAA;IAC3B,CAAC;IAEM,MAAM,CAAC,GAAW;QACvB,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACtB,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * Tracks cloud-audio subscription writes so LocalMiniappRuntime can dedupe\n * successful writes without losing retryability after transient Core/network\n * failures.\n *\n * Failure mode this protects:\n * 1. Local captions subscribes to transcription.\n * 2. The first Cloud V2 `PUT /api/audio/subscriptions` throws while the socket\n * is reconnecting or Core is briefly unreachable.\n * 3. A reconnect/resync recomputes the same desired subscription set.\n *\n * If we mark the set as \"last applied\" before the PUT succeeds, step 3 is\n * incorrectly deduped and captions can wait forever even though Cloud V2 later\n * reconnects. So `begin()` only blocks exact duplicates while a write is in\n * flight; only `succeeded()` promotes that key to the applied state.\n */\nexport class CloudAudioSubscriptionSync {\n private lastAppliedKey = \"\"\n private pendingKey = \"\"\n\n public begin(nextKey: string): boolean {\n if (nextKey === this.lastAppliedKey || nextKey === this.pendingKey) {\n return false\n }\n this.pendingKey = nextKey\n return true\n }\n\n public succeeded(key: string): void {\n if (this.pendingKey === key) {\n this.pendingKey = \"\"\n }\n this.lastAppliedKey = key\n }\n\n public failed(key: string): void {\n if (this.pendingKey === key) {\n this.pendingKey = \"\"\n }\n }\n}\n"]}
1
+ {"version":3,"file":"CloudAudioSubscriptionSync.js","sourceRoot":"","sources":["../../src/services/CloudAudioSubscriptionSync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,0BAA0B;IAC7B,cAAc,GAAG,EAAE,CAAA;IACnB,UAAU,GAAG,EAAE,CAAA;IAEhB,KAAK,CAAC,OAAe;QAC1B,kEAAkE;QAClE,IAAI,OAAO,KAAK,IAAI,CAAC,UAAU,EAAE,CAAC;YAChC,OAAO,KAAK,CAAA;QACd,CAAC;QACD,wEAAwE;QACxE,wEAAwE;QACxE,iEAAiE;QACjE,0EAA0E;QAC1E,wEAAwE;QACxE,uEAAuE;QACvE,wEAAwE;QACxE,4EAA4E;QAC5E,IAAI,OAAO,KAAK,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;YAC9D,OAAO,KAAK,CAAA;QACd,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAEM,SAAS,CAAC,GAAW;QAC1B,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACtB,CAAC;QACD,IAAI,CAAC,cAAc,GAAG,GAAG,CAAA;IAC3B,CAAC;IAEM,MAAM,CAAC,GAAW;QACvB,IAAI,IAAI,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAA;QACtB,CAAC;IACH,CAAC;CACF","sourcesContent":["/**\n * Tracks cloud-audio subscription writes so LocalMiniappRuntime can dedupe\n * successful writes without losing retryability after transient Core/network\n * failures.\n *\n * Failure mode this protects:\n * 1. Local captions subscribes to transcription.\n * 2. The first Cloud V2 `PUT /api/audio/subscriptions` throws while the socket\n * is reconnecting or Core is briefly unreachable.\n * 3. A reconnect/resync recomputes the same desired subscription set.\n *\n * If we mark the set as \"last applied\" before the PUT succeeds, step 3 is\n * incorrectly deduped and captions can wait forever even though Cloud V2 later\n * reconnects. So `begin()` only blocks exact duplicates while a write is in\n * flight; only `succeeded()` promotes that key to the applied state.\n */\nexport class CloudAudioSubscriptionSync {\n private lastAppliedKey = \"\"\n private pendingKey = \"\"\n\n public begin(nextKey: string): boolean {\n // Exact duplicate of the write already in flight — nothing to do.\n if (nextKey === this.pendingKey) {\n return false\n }\n // Matches the last successfully applied set, but ONLY skip when nothing\n // else is in flight. If a different write is pending (e.g. desired went\n // fr-FR -> [] -> fr-FR while the [] write is still on the wire),\n // lastAppliedKey is stale: it names what was applied BEFORE the in-flight\n // write lands. Skipping here would drop the re-subscribe and strand the\n // cloud on the intermediate (empty) set — captions silently die on any\n // rapid A -> B -> A subscription churn. The cloud's own version counter\n // resolves ordering between the concurrent writes, so sending both is safe.\n if (nextKey === this.lastAppliedKey && this.pendingKey === \"\") {\n return false\n }\n this.pendingKey = nextKey\n return true\n }\n\n public succeeded(key: string): void {\n if (this.pendingKey === key) {\n this.pendingKey = \"\"\n }\n this.lastAppliedKey = key\n }\n\n public failed(key: string): void {\n if (this.pendingKey === key) {\n this.pendingKey = \"\"\n }\n }\n}\n"]}
@@ -39,6 +39,18 @@ export declare const cloudClientService: {
39
39
  runtime: string;
40
40
  } | null): void;
41
41
  getPreinstalledMiniappRegistry(): Promise<PreinstalledMiniappRegistry>;
42
+ /**
43
+ * Resolve the stable Core-owned Mentra user id.
44
+ *
45
+ * Storage must use this identity rather than the short-lived Core access
46
+ * token. A previously verified id is restored from MMKV so local miniapps
47
+ * remain available after an offline process restart. On first sign-in,
48
+ * callers join the auth module's single-flight exchange/refresh instead of
49
+ * falling back to an anonymous namespace.
50
+ */
51
+ resolveMentraUserId(): Promise<string>;
52
+ /** Read the stable Mentra user id after async identity resolution. */
53
+ getMentraUserId(): string;
42
54
  getMiniappAuthToken(packageName: string, opts?: {
43
55
  minTtlMs?: number;
44
56
  devAttestation?: string;
@@ -136,6 +148,9 @@ export declare const cloudClientService: {
136
148
  status: import("@mentra/cloud-client").ReportStatus;
137
149
  }>;
138
150
  };
151
+ supportProfile: {
152
+ update(input: import("@mentra/cloud-client").SupportStateInput): Promise<import("@mentra/cloud-client").SupportProfileUpdateResult>;
153
+ };
139
154
  };
140
155
  hasAudioSubscriptions(): boolean;
141
156
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CloudClientService.d.ts","sourceRoot":"","sources":["../../src/services/CloudClientService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAC,WAAW,EAAiC,MAAM,mCAAmC,CAAA;AAC7F,OAAO,KAAK,EAAC,2BAA2B,EAAkB,MAAM,mCAAmC,CAAA;AAEnG,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAC,MAAM,wBAAwB,CAAA;AAKjG,OAAO,EAAC,KAAK,yBAAyB,EAAE,KAAK,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AASvF,KAAK,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;AAmajD;;;GAGG;AACH,eAAO,MAAM,kBAAkB;IAC7B;;;;OAIG;YACK,IAAI;IAMZ;;;;OAIG;0BACmB;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,GAAG,IAAI;sCAoB3B,OAAO,CAAC,2BAA2B,CAAC;qCAQ7D,MAAM,SACZ;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAC,GAClD,OAAO,CAAC,gBAAgB,CAAC;IAe5B,uEAAuE;YAC/D,IAAI;IAkBZ,qFAAqF;6BAC7D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;sCAIb,MAAM;;;;IAKxC,2EAA2E;8BAClD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;qCAIf,MAAM;;;;;;;;gCAIX,MAAM;IAKlC,mEAAmE;mBACpD,OAAO;IAItB,4EAA4E;iCAC/C,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI;IAOtE,0EAA0E;2BAC7C,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;0BAU1C,UAAU,GAAG,IAAI;qBAItB,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,GAAG,MAAM,IAAI;sBAO1C,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI;iBAO9C,yBAAyB;kBAIxB,MAAM;gCAIQ,OAAO,CAAC,MAAM,CAAC;wBAIvB,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI,GAAG,MAAM,IAAI;;oBAQhE,MAAM,YAAY,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;;;wBAOnE,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;8BAIrD,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;+BAI9D,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;0BAIvE,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;6BAuBxD,OAAO;CAGjC,CAAA"}
1
+ {"version":3,"file":"CloudClientService.d.ts","sourceRoot":"","sources":["../../src/services/CloudClientService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAC,WAAW,EAAgD,MAAM,mCAAmC,CAAA;AAC5G,OAAO,KAAK,EAAC,2BAA2B,EAAkB,MAAM,mCAAmC,CAAA;AAGnG,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAC,MAAM,wBAAwB,CAAA;AAMjG,OAAO,EAAC,KAAK,yBAAyB,EAAE,KAAK,gBAAgB,EAAC,MAAM,mBAAmB,CAAA;AAYvF,KAAK,SAAS,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;AAudjD;;;GAGG;AACH,eAAO,MAAM,kBAAkB;IAC7B;;;;OAIG;YACK,IAAI;IAMZ;;;;OAIG;0BACmB;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,GAAG,IAAI;sCAoB3B,OAAO,CAAC,2BAA2B,CAAC;IAO5E;;;;;;;;OAQG;2BAC0B,OAAO,CAAC,MAAM,CAAC;IAY5C,sEAAsE;uBACnD,MAAM;qCAOV,MAAM,SACZ;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAC,GAClD,OAAO,CAAC,gBAAgB,CAAC;IAe5B,uEAAuE;YAC/D,IAAI;IAuBZ,qFAAqF;6BAC7D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;sCAIb,MAAM;;;;IAKxC,2EAA2E;8BAClD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;qCAIf,MAAM;;;;;;;;gCAIX,MAAM;IAKlC,mEAAmE;mBACpD,OAAO;IAItB,4EAA4E;iCAC/C,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI;IAOtE,0EAA0E;2BAC7C,iBAAiB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;0BAU1C,UAAU,GAAG,IAAI;qBAItB,CAAC,CAAC,EAAE,iBAAiB,KAAK,IAAI,GAAG,MAAM,IAAI;sBAO1C,CAAC,CAAC,EAAE,eAAe,KAAK,IAAI,GAAG,MAAM,IAAI;iBAO9C,yBAAyB;kBAIxB,MAAM;gCAIQ,OAAO,CAAC,MAAM,CAAC;wBAIvB,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI,GAAG,MAAM,IAAI;;oBAQhE,MAAM,YAAY,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;;;wBAOnE,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;8BAIrD,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;+BAI9D,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;0BAIvE,UAAU,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;6BA4BxD,OAAO;CAGjC,CAAA"}
@@ -13,22 +13,28 @@
13
13
  * The local-miniapp path drives the cloud's transcription/translation through
14
14
  * this service.
15
15
  */
16
- import { CloudClient, setNativeUdp, setSecureStorage } from "@mentra/cloud-client/react-native";
16
+ import { CloudClient, setNativeHttp, setNativeUdp, setSecureStorage } from "@mentra/cloud-client/react-native";
17
+ import { Platform } from "react-native";
17
18
  import BluetoothSdk from "@mentra/bluetooth-sdk/internal";
19
+ import CrustModule from "@mentra/crust";
18
20
  import { getAuth, getConfigValues } from "../runtime/bootstrap";
19
21
  import { useSettingsStore, SETTINGS } from "../stores/settings";
20
22
  import { createCloudUdpSocket } from "../utils/cloudClient/RnUdpAdapter";
21
23
  import { cloudSecureStore } from "../utils/cloudClient/cloudSecureStore";
24
+ import { storage as mmkvStorage } from "../utils/storage";
22
25
  import { useCloudClientStatusStore } from "../stores/cloudClientStatus";
23
26
  import { islandNotifications } from "./NotificationsEmitter";
24
27
  import { BgTimer } from "../utils/timers";
25
28
  import { logCloudV2TranscriptMetric } from "./CloudTranscriptE2EMetrics";
29
+ import { LocalMiniappUserIdentity } from "./LocalMiniappUserIdentity";
30
+ import { nativeHttpResponseBody } from "./NativeHttpResponse";
26
31
  const LOG_TAG = "cloudClient";
27
32
  // Persistent cloud-disconnect detector: the cloud-client reconnect loop is infinite
28
33
  // and never surfaces a "giving up" signal, so "persistent failure" = the session has
29
34
  // been continuously NOT connected for this long. A quick reconnect cancels it; brief
30
35
  // flaps that recover don't fire. Raised as engine.notifications(connection_failed_persistent).
31
36
  const CLOUD_PERSISTENT_FAILURE_MS = 60_000;
37
+ const LOCAL_MINIAPP_USER_ID_KEY = "mentra.localMiniapp.userId";
32
38
  /** Cancel the pending persistent-failure alarm + re-arm for the next outage. */
33
39
  function clearPersistentFailureAlarm() {
34
40
  if (persistentFailureTimer) {
@@ -58,6 +64,22 @@ let authStateUnsubscribe = null;
58
64
  let localDevRuntimeToken = null;
59
65
  let lc3FrameSizeUnsubscribe = null;
60
66
  let coreTokenSyncPromise = null;
67
+ const localMiniappUserIdentity = new LocalMiniappUserIdentity({
68
+ get() {
69
+ const result = mmkvStorage.load(LOCAL_MINIAPP_USER_ID_KEY);
70
+ return result.is_ok() ? result.value : null;
71
+ },
72
+ set(userId) {
73
+ const result = mmkvStorage.save(LOCAL_MINIAPP_USER_ID_KEY, userId);
74
+ if (result.is_error())
75
+ throw result.error;
76
+ },
77
+ remove() {
78
+ const result = mmkvStorage.remove(LOCAL_MINIAPP_USER_ID_KEY);
79
+ if (result.is_error())
80
+ throw result.error;
81
+ },
82
+ });
61
83
  const transcriptListeners = new Set();
62
84
  const translationListeners = new Set();
63
85
  const statusListeners = new Set();
@@ -97,6 +119,7 @@ async function syncCoreAccessTokenToBluetoothInternal() {
97
119
  if (c !== client) {
98
120
  throw new Error("cloud client changed while syncing core token");
99
121
  }
122
+ localMiniappUserIdentity.remember(c.auth.identity.mentraUserId);
100
123
  const result = await useSettingsStore.getState().setSetting(SETTINGS.core_token.key, token, false);
101
124
  if (result.is_error()) {
102
125
  throw result.error;
@@ -235,6 +258,14 @@ function ensureAuthWatch() {
235
258
  let reconnectPending = false;
236
259
  try {
237
260
  const sub = auth.onStateChange((event, session) => {
261
+ if (event === "SIGNED_OUT") {
262
+ localMiniappUserIdentity.forget();
263
+ return;
264
+ }
265
+ // A new sign-in may belong to a different account. Force the next
266
+ // storage request to resolve and persist that account's Core identity.
267
+ if (event === "SIGNED_IN")
268
+ localMiniappUserIdentity.forget();
238
269
  if (!session?.token)
239
270
  return;
240
271
  if (connected || reconnectPending)
@@ -298,6 +329,20 @@ function ensureTransports() {
298
329
  transportsReady = true;
299
330
  setNativeUdp(() => createCloudUdpSocket());
300
331
  setSecureStorage(cloudSecureStore);
332
+ if (Platform.OS !== "android")
333
+ return;
334
+ setNativeHttp(async (input, init) => {
335
+ if (typeof input !== "string" || (init?.body != null && typeof init.body !== "string")) {
336
+ return globalThis.fetch(input, init);
337
+ }
338
+ const headers = Object.fromEntries(new Headers(init?.headers).entries());
339
+ const result = await CrustModule.nativeHttpRequest(init?.method ?? "GET", input, headers, init?.body ?? null);
340
+ return new Response(nativeHttpResponseBody(result.status, result.body), {
341
+ status: result.status,
342
+ statusText: result.statusText,
343
+ headers: result.headers,
344
+ });
345
+ });
301
346
  }
302
347
  function clearRuntimeEventSubscriptions() {
303
348
  runtimeStatusUnsubscribe?.();
@@ -343,6 +388,12 @@ function construct() {
343
388
  // LC3 at 16 kHz with the frame size the encoder emits.
344
389
  audio: { codec: "lc3", sampleRate: 16000, frameSizeBytes: frameSizeBytes() },
345
390
  auth,
391
+ timers: {
392
+ setTimeout: (callback, delayMs) => BgTimer.setTimeout(callback, delayMs),
393
+ clearTimeout: (handle) => BgTimer.clearTimeout(handle),
394
+ setInterval: (callback, intervalMs) => BgTimer.setInterval(callback, intervalMs),
395
+ clearInterval: (handle) => BgTimer.clearInterval(handle),
396
+ },
346
397
  logger: cloudLogger,
347
398
  });
348
399
  const c = client;
@@ -369,6 +420,7 @@ function construct() {
369
420
  return;
370
421
  connected = true;
371
422
  console.log(`${LOG_TAG}: runtime connected`);
423
+ console.log(`${LOG_TAG}: debug: ws-session-debug connected`);
372
424
  // Cloud is up — cancel any pending persistent-failure alarm and re-arm for the
373
425
  // next outage.
374
426
  clearPersistentFailureAlarm();
@@ -384,6 +436,7 @@ function construct() {
384
436
  return;
385
437
  connected = false;
386
438
  console.log(`${LOG_TAG}: runtime disconnected (${info.reason})`);
439
+ console.log(`${LOG_TAG}: debug: ws-session-debug disconnected reason=${info.reason} willStayDown=${/superseded by newer session/i.test(info.reason)}`);
387
440
  // Arm the persistent-failure alarm once; if we're still down when it fires, raise
388
441
  // the notification. A reconnect within the window cancels it (onConnected above).
389
442
  if (!persistentFailureTimer && !persistentFailureNotified) {
@@ -462,6 +515,35 @@ export const cloudClientService = {
462
515
  throw new Error("cloud client core is unavailable");
463
516
  return c.core.miniapps.getRegistry();
464
517
  },
518
+ /**
519
+ * Resolve the stable Core-owned Mentra user id.
520
+ *
521
+ * Storage must use this identity rather than the short-lived Core access
522
+ * token. A previously verified id is restored from MMKV so local miniapps
523
+ * remain available after an offline process restart. On first sign-in,
524
+ * callers join the auth module's single-flight exchange/refresh instead of
525
+ * falling back to an anonymous namespace.
526
+ */
527
+ async resolveMentraUserId() {
528
+ return localMiniappUserIdentity.resolve(async () => {
529
+ if (!client)
530
+ this.init();
531
+ const c = client;
532
+ if (!c)
533
+ throw new Error("cloud client not initialized");
534
+ await c.auth.getCoreToken();
535
+ if (c !== client)
536
+ throw new Error("cloud client changed while resolving user identity");
537
+ return c.auth.identity.mentraUserId;
538
+ });
539
+ },
540
+ /** Read the stable Mentra user id after async identity resolution. */
541
+ getMentraUserId() {
542
+ const userId = localMiniappUserIdentity.get();
543
+ if (!userId)
544
+ throw new Error("Mentra user identity is unavailable");
545
+ return userId;
546
+ },
465
547
  async getMiniappAuthToken(packageName, opts) {
466
548
  if (!client)
467
549
  this.init();
@@ -491,6 +573,11 @@ export const cloudClientService = {
491
573
  clearPersistentFailureAlarm();
492
574
  const wasConnected = connected;
493
575
  client = null;
576
+ // stop() is part of the logout lifecycle and runs before the host emits
577
+ // SIGNED_OUT. Remove the persisted namespace owner here so a later account
578
+ // can never inherit it. A force-stop/process kill does not call stop(), so
579
+ // the cached id still survives the offline cold-start case.
580
+ localMiniappUserIdentity.forget();
494
581
  localDevRuntimeToken = null;
495
582
  connected = false;
496
583
  resetRuntimeStatus();
@@ -619,6 +706,11 @@ export const cloudClientService = {
619
706
  return getCoreClient().reports.complete(...args);
620
707
  },
621
708
  },
709
+ supportProfile: {
710
+ update(...args) {
711
+ return getCoreClient().supportProfile.update(...args);
712
+ },
713
+ },
622
714
  },
623
715
  hasAudioSubscriptions() {
624
716
  return audioSubscriptions.length > 0;