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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (503) hide show
  1. package/README.md +55 -18
  2. package/build/bluetooth-sdk/debug.d.ts +2 -0
  3. package/build/bluetooth-sdk/debug.d.ts.map +1 -0
  4. package/build/bluetooth-sdk/debug.js +2 -0
  5. package/build/bluetooth-sdk/debug.js.map +1 -0
  6. package/build/bluetooth-sdk/index.d.ts +3 -0
  7. package/build/bluetooth-sdk/index.d.ts.map +1 -0
  8. package/build/bluetooth-sdk/index.js +3 -0
  9. package/build/bluetooth-sdk/index.js.map +1 -0
  10. package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
  11. package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
  12. package/build/bluetooth-sdk/photo-receiver.js +3 -0
  13. package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
  14. package/build/bluetooth-sdk/react.d.ts +2 -0
  15. package/build/bluetooth-sdk/react.d.ts.map +1 -0
  16. package/build/bluetooth-sdk/react.js +2 -0
  17. package/build/bluetooth-sdk/react.js.map +1 -0
  18. package/build/bluetooth-sdk/types.d.ts +2 -0
  19. package/build/bluetooth-sdk/types.d.ts.map +1 -0
  20. package/build/bluetooth-sdk/types.js +2 -0
  21. package/build/bluetooth-sdk/types.js.map +1 -0
  22. package/build/engine.d.ts +24 -16
  23. package/build/engine.d.ts.map +1 -1
  24. package/build/engine.js +9 -4
  25. package/build/engine.js.map +1 -1
  26. package/build/facades/dev.d.ts +3 -2
  27. package/build/facades/dev.d.ts.map +1 -1
  28. package/build/facades/dev.js +18 -12
  29. package/build/facades/dev.js.map +1 -1
  30. package/build/facades/display.d.ts +1 -1
  31. package/build/facades/display.d.ts.map +1 -1
  32. package/build/facades/display.js +1 -1
  33. package/build/facades/display.js.map +1 -1
  34. package/build/facades/gallery.js +1 -1
  35. package/build/facades/gallery.js.map +1 -1
  36. package/build/facades/glasses.d.ts +4 -13
  37. package/build/facades/glasses.d.ts.map +1 -1
  38. package/build/facades/glasses.js +21 -6
  39. package/build/facades/glasses.js.map +1 -1
  40. package/build/facades/glassesSettings.d.ts.map +1 -1
  41. package/build/facades/glassesSettings.js +1 -0
  42. package/build/facades/glassesSettings.js.map +1 -1
  43. package/build/facades/miniapps.d.ts +4 -0
  44. package/build/facades/miniapps.d.ts.map +1 -1
  45. package/build/facades/miniapps.js +5 -0
  46. package/build/facades/miniapps.js.map +1 -1
  47. package/build/facades/ota.d.ts +14 -16
  48. package/build/facades/ota.d.ts.map +1 -1
  49. package/build/facades/ota.js +22 -7
  50. package/build/facades/ota.js.map +1 -1
  51. package/build/facades/pairing.d.ts +8 -5
  52. package/build/facades/pairing.d.ts.map +1 -1
  53. package/build/facades/pairing.js +12 -10
  54. package/build/facades/pairing.js.map +1 -1
  55. package/build/facades/permissions.d.ts +10 -0
  56. package/build/facades/permissions.d.ts.map +1 -1
  57. package/build/facades/permissions.js +10 -0
  58. package/build/facades/permissions.js.map +1 -1
  59. package/build/facades/phoneNotifications.d.ts +0 -4
  60. package/build/facades/phoneNotifications.d.ts.map +1 -1
  61. package/build/facades/phoneNotifications.js +4 -14
  62. package/build/facades/phoneNotifications.js.map +1 -1
  63. package/build/facades/speech.d.ts +7 -6
  64. package/build/facades/speech.d.ts.map +1 -1
  65. package/build/facades/speech.js +1 -1
  66. package/build/facades/speech.js.map +1 -1
  67. package/build/generated/releaseMetadata.d.ts +12 -0
  68. package/build/generated/releaseMetadata.d.ts.map +1 -0
  69. package/build/generated/releaseMetadata.js +10 -0
  70. package/build/generated/releaseMetadata.js.map +1 -0
  71. package/build/index.d.ts +10 -8
  72. package/build/index.d.ts.map +1 -1
  73. package/build/index.js +6 -5
  74. package/build/index.js.map +1 -1
  75. package/build/react/MentraLiveOtaFlow.d.ts +38 -0
  76. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
  77. package/build/react/MentraLiveOtaFlow.js +528 -0
  78. package/build/react/MentraLiveOtaFlow.js.map +1 -0
  79. package/build/react/index.d.ts +2 -0
  80. package/build/react/index.d.ts.map +1 -0
  81. package/build/react/index.js +2 -0
  82. package/build/react/index.js.map +1 -0
  83. package/build/react/useEngineSnapshot.d.ts +2 -0
  84. package/build/react/useEngineSnapshot.d.ts.map +1 -0
  85. package/build/react/useEngineSnapshot.js +14 -0
  86. package/build/react/useEngineSnapshot.js.map +1 -0
  87. package/build/runtime/bootstrap.d.ts +24 -1
  88. package/build/runtime/bootstrap.d.ts.map +1 -1
  89. package/build/runtime/bootstrap.js +17 -0
  90. package/build/runtime/bootstrap.js.map +1 -1
  91. package/build/runtime/scanQrSeam.d.ts +7 -0
  92. package/build/runtime/scanQrSeam.d.ts.map +1 -0
  93. package/build/runtime/scanQrSeam.js +16 -0
  94. package/build/runtime/scanQrSeam.js.map +1 -0
  95. package/build/services/AppRegistry.d.ts +41 -57
  96. package/build/services/AppRegistry.d.ts.map +1 -1
  97. package/build/services/AppRegistry.js +208 -144
  98. package/build/services/AppRegistry.js.map +1 -1
  99. package/build/services/AudioCloudUplink.d.ts +12 -0
  100. package/build/services/AudioCloudUplink.d.ts.map +1 -1
  101. package/build/services/AudioCloudUplink.js +22 -1
  102. package/build/services/AudioCloudUplink.js.map +1 -1
  103. package/build/services/AudioPlaybackService.d.ts +41 -2
  104. package/build/services/AudioPlaybackService.d.ts.map +1 -1
  105. package/build/services/AudioPlaybackService.js +250 -33
  106. package/build/services/AudioPlaybackService.js.map +1 -1
  107. package/build/services/BlobStore.d.ts +2 -1
  108. package/build/services/BlobStore.d.ts.map +1 -1
  109. package/build/services/BlobStore.js +17 -9
  110. package/build/services/BlobStore.js.map +1 -1
  111. package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
  112. package/build/services/CloudAudioSubscriptionSync.js +13 -1
  113. package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
  114. package/build/services/CloudClientService.d.ts +15 -0
  115. package/build/services/CloudClientService.d.ts.map +1 -1
  116. package/build/services/CloudClientService.js +93 -1
  117. package/build/services/CloudClientService.js.map +1 -1
  118. package/build/services/DeviceEventRouter.js +5 -5
  119. package/build/services/DeviceEventRouter.js.map +1 -1
  120. package/build/services/ForegroundLocationPermission.d.ts +13 -0
  121. package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
  122. package/build/services/ForegroundLocationPermission.js +12 -0
  123. package/build/services/ForegroundLocationPermission.js.map +1 -0
  124. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  125. package/build/services/GlassesSettingsSync.js +9 -3
  126. package/build/services/GlassesSettingsSync.js.map +1 -1
  127. package/build/services/GlassesStatusProjection.d.ts +2 -1
  128. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  129. package/build/services/GlassesStatusProjection.js +15 -8
  130. package/build/services/GlassesStatusProjection.js.map +1 -1
  131. package/build/services/HotspotOtaTransport.d.ts +29 -0
  132. package/build/services/HotspotOtaTransport.d.ts.map +1 -0
  133. package/build/services/HotspotOtaTransport.js +146 -0
  134. package/build/services/HotspotOtaTransport.js.map +1 -0
  135. package/build/services/HotspotShutdown.d.ts +17 -0
  136. package/build/services/HotspotShutdown.d.ts.map +1 -0
  137. package/build/services/HotspotShutdown.js +29 -0
  138. package/build/services/HotspotShutdown.js.map +1 -0
  139. package/build/services/LocalDisplayManager.d.ts +15 -0
  140. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  141. package/build/services/LocalDisplayManager.js +106 -20
  142. package/build/services/LocalDisplayManager.js.map +1 -1
  143. package/build/services/LocalMiniappRuntime.d.ts +74 -2
  144. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  145. package/build/services/LocalMiniappRuntime.js +785 -291
  146. package/build/services/LocalMiniappRuntime.js.map +1 -1
  147. package/build/services/LocalMiniappStorage.d.ts +32 -0
  148. package/build/services/LocalMiniappStorage.d.ts.map +1 -0
  149. package/build/services/LocalMiniappStorage.js +66 -0
  150. package/build/services/LocalMiniappStorage.js.map +1 -0
  151. package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
  152. package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
  153. package/build/services/LocalMiniappUserIdentity.js +43 -0
  154. package/build/services/LocalMiniappUserIdentity.js.map +1 -0
  155. package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
  156. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  157. package/build/services/LocalSttFallbackCoordinator.js +18 -12
  158. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  159. package/build/services/MicStateCoordinator.d.ts +42 -1
  160. package/build/services/MicStateCoordinator.d.ts.map +1 -1
  161. package/build/services/MicStateCoordinator.js +141 -3
  162. package/build/services/MicStateCoordinator.js.map +1 -1
  163. package/build/services/MiniappLauncher.d.ts.map +1 -1
  164. package/build/services/MiniappLauncher.js +23 -3
  165. package/build/services/MiniappLauncher.js.map +1 -1
  166. package/build/services/MiniappLiveness.d.ts +12 -0
  167. package/build/services/MiniappLiveness.d.ts.map +1 -0
  168. package/build/services/MiniappLiveness.js +16 -0
  169. package/build/services/MiniappLiveness.js.map +1 -0
  170. package/build/services/NativeHttpResponse.d.ts +3 -0
  171. package/build/services/NativeHttpResponse.d.ts.map +1 -0
  172. package/build/services/NativeHttpResponse.js +6 -0
  173. package/build/services/NativeHttpResponse.js.map +1 -0
  174. package/build/services/OtaArtifactDownloader.d.ts +65 -0
  175. package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
  176. package/build/services/OtaArtifactDownloader.js +226 -0
  177. package/build/services/OtaArtifactDownloader.js.map +1 -0
  178. package/build/services/OtaAutoChain.d.ts +34 -0
  179. package/build/services/OtaAutoChain.d.ts.map +1 -0
  180. package/build/services/OtaAutoChain.js +83 -0
  181. package/build/services/OtaAutoChain.js.map +1 -0
  182. package/build/services/OtaErrorMapping.d.ts +18 -0
  183. package/build/services/OtaErrorMapping.d.ts.map +1 -0
  184. package/build/services/OtaErrorMapping.js +63 -0
  185. package/build/services/OtaErrorMapping.js.map +1 -0
  186. package/build/services/OtaInstallCoordinator.d.ts +95 -15
  187. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  188. package/build/services/OtaInstallCoordinator.js +577 -130
  189. package/build/services/OtaInstallCoordinator.js.map +1 -1
  190. package/build/services/OtaService.d.ts.map +1 -1
  191. package/build/services/OtaService.js +8 -1
  192. package/build/services/OtaService.js.map +1 -1
  193. package/build/services/OtaUpdateCheckService.d.ts +39 -4
  194. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  195. package/build/services/OtaUpdateCheckService.js +138 -22
  196. package/build/services/OtaUpdateCheckService.js.map +1 -1
  197. package/build/services/PhoneCalendarHelpers.d.ts +32 -0
  198. package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
  199. package/build/services/PhoneCalendarHelpers.js +157 -0
  200. package/build/services/PhoneCalendarHelpers.js.map +1 -0
  201. package/build/services/PhoneCalendarService.d.ts +5 -0
  202. package/build/services/PhoneCalendarService.d.ts.map +1 -0
  203. package/build/services/PhoneCalendarService.js +45 -0
  204. package/build/services/PhoneCalendarService.js.map +1 -0
  205. package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
  206. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
  207. package/build/services/PhoneCameraFovCoordinator.js +194 -0
  208. package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
  209. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  210. package/build/services/PhoneNotificationsSync.js +12 -10
  211. package/build/services/PhoneNotificationsSync.js.map +1 -1
  212. package/build/services/PhonePhotoCoordinator.d.ts +26 -2
  213. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  214. package/build/services/PhonePhotoCoordinator.js +79 -9
  215. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  216. package/build/services/PhoneStreamCoordinator.d.ts +8 -1
  217. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  218. package/build/services/PhoneStreamCoordinator.js +125 -13
  219. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  220. package/build/services/PhoneVideoCoordinator.d.ts +2 -0
  221. package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
  222. package/build/services/PhoneVideoCoordinator.js +10 -0
  223. package/build/services/PhoneVideoCoordinator.js.map +1 -1
  224. package/build/services/SceneRenderer.d.ts.map +1 -1
  225. package/build/services/SceneRenderer.js +15 -0
  226. package/build/services/SceneRenderer.js.map +1 -1
  227. package/build/services/SentenceTtsPipeline.d.ts +31 -0
  228. package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
  229. package/build/services/SentenceTtsPipeline.js +67 -0
  230. package/build/services/SentenceTtsPipeline.js.map +1 -0
  231. package/build/services/SupportProfileSync.d.ts +22 -0
  232. package/build/services/SupportProfileSync.d.ts.map +1 -0
  233. package/build/services/SupportProfileSync.js +213 -0
  234. package/build/services/SupportProfileSync.js.map +1 -0
  235. package/build/services/TranscriptionRouting.d.ts +12 -0
  236. package/build/services/TranscriptionRouting.d.ts.map +1 -0
  237. package/build/services/TranscriptionRouting.js +24 -0
  238. package/build/services/TranscriptionRouting.js.map +1 -0
  239. package/build/services/TtsTextSanitizer.d.ts +5 -0
  240. package/build/services/TtsTextSanitizer.d.ts.map +1 -0
  241. package/build/services/TtsTextSanitizer.js +61 -0
  242. package/build/services/TtsTextSanitizer.js.map +1 -0
  243. package/build/services/WifiAdbRequest.d.ts +17 -0
  244. package/build/services/WifiAdbRequest.d.ts.map +1 -0
  245. package/build/services/WifiAdbRequest.js +35 -0
  246. package/build/services/WifiAdbRequest.js.map +1 -0
  247. package/build/services/asg/asgCameraApi.d.ts +43 -0
  248. package/build/services/asg/asgCameraApi.d.ts.map +1 -1
  249. package/build/services/asg/asgCameraApi.js +509 -26
  250. package/build/services/asg/asgCameraApi.js.map +1 -1
  251. package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
  252. package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
  253. package/build/services/asg/cameraRollExportCoordinator.js +618 -0
  254. package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
  255. package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
  256. package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
  257. package/build/services/asg/cameraRollExportLedger.js +78 -0
  258. package/build/services/asg/cameraRollExportLedger.js.map +1 -0
  259. package/build/services/asg/galleryNotices.d.ts +1 -1
  260. package/build/services/asg/galleryNotices.d.ts.map +1 -1
  261. package/build/services/asg/galleryNotices.js.map +1 -1
  262. package/build/services/asg/galleryPathMigration.d.ts +3 -0
  263. package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
  264. package/build/services/asg/galleryPathMigration.js +26 -0
  265. package/build/services/asg/galleryPathMigration.js.map +1 -0
  266. package/build/services/asg/gallerySettingsService.d.ts +1 -0
  267. package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
  268. package/build/services/asg/gallerySettingsService.js +2 -0
  269. package/build/services/asg/gallerySettingsService.js.map +1 -1
  270. package/build/services/asg/gallerySyncService.d.ts.map +1 -1
  271. package/build/services/asg/gallerySyncService.js +162 -56
  272. package/build/services/asg/gallerySyncService.js.map +1 -1
  273. package/build/services/asg/galleryTransferLedger.d.ts +58 -0
  274. package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
  275. package/build/services/asg/galleryTransferLedger.js +225 -0
  276. package/build/services/asg/galleryTransferLedger.js.map +1 -0
  277. package/build/services/asg/localNetworkTransport.d.ts +15 -0
  278. package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
  279. package/build/services/asg/localNetworkTransport.js +144 -0
  280. package/build/services/asg/localNetworkTransport.js.map +1 -0
  281. package/build/services/asg/localStorageService.d.ts +18 -0
  282. package/build/services/asg/localStorageService.d.ts.map +1 -1
  283. package/build/services/asg/localStorageService.js +168 -19
  284. package/build/services/asg/localStorageService.js.map +1 -1
  285. package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
  286. package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
  287. package/build/services/asg/mediaProcessingQueue.js +193 -62
  288. package/build/services/asg/mediaProcessingQueue.js.map +1 -1
  289. package/build/services/audioPlaybackAssets.d.ts +8 -0
  290. package/build/services/audioPlaybackAssets.d.ts.map +1 -0
  291. package/build/services/audioPlaybackAssets.js +7 -0
  292. package/build/services/audioPlaybackAssets.js.map +1 -0
  293. package/build/services/gallerySyncClock.js +1 -1
  294. package/build/services/gallerySyncClock.js.map +1 -1
  295. package/build/services/glassesClockSync.d.ts.map +1 -1
  296. package/build/services/glassesClockSync.js +6 -2
  297. package/build/services/glassesClockSync.js.map +1 -1
  298. package/build/services/manifestActions.d.ts +7 -0
  299. package/build/services/manifestActions.d.ts.map +1 -0
  300. package/build/services/manifestActions.js +25 -0
  301. package/build/services/manifestActions.js.map +1 -0
  302. package/build/services/otaDisplayState.d.ts +23 -12
  303. package/build/services/otaDisplayState.d.ts.map +1 -1
  304. package/build/services/otaDisplayState.js +36 -14
  305. package/build/services/otaDisplayState.js.map +1 -1
  306. package/build/services/otaInstallPolicy.d.ts +16 -4
  307. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  308. package/build/services/otaInstallPolicy.js +24 -3
  309. package/build/services/otaInstallPolicy.js.map +1 -1
  310. package/build/services/otaLegacyMapping.d.ts +1 -1
  311. package/build/services/otaLegacyMapping.d.ts.map +1 -1
  312. package/build/services/otaLegacyMapping.js.map +1 -1
  313. package/build/services/otaManifestPolicy.d.ts +14 -0
  314. package/build/services/otaManifestPolicy.d.ts.map +1 -0
  315. package/build/services/otaManifestPolicy.js +19 -0
  316. package/build/services/otaManifestPolicy.js.map +1 -0
  317. package/build/services/otaManifestUrl.d.ts +3 -0
  318. package/build/services/otaManifestUrl.d.ts.map +1 -0
  319. package/build/services/otaManifestUrl.js +38 -0
  320. package/build/services/otaManifestUrl.js.map +1 -0
  321. package/build/services/slimStreamStatus.d.ts +11 -0
  322. package/build/services/slimStreamStatus.d.ts.map +1 -1
  323. package/build/services/slimStreamStatus.js +14 -4
  324. package/build/services/slimStreamStatus.js.map +1 -1
  325. package/build/stores/apps.d.ts.map +1 -1
  326. package/build/stores/apps.js +11 -0
  327. package/build/stores/apps.js.map +1 -1
  328. package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
  329. package/build/stores/bluetoothSettingKeys.js +2 -0
  330. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  331. package/build/stores/gallerySync.d.ts +2 -0
  332. package/build/stores/gallerySync.d.ts.map +1 -1
  333. package/build/stores/gallerySync.js +2 -0
  334. package/build/stores/gallerySync.js.map +1 -1
  335. package/build/stores/glasses.d.ts.map +1 -1
  336. package/build/stores/glasses.js +3 -0
  337. package/build/stores/glasses.js.map +1 -1
  338. package/build/stores/settings.d.ts +17 -0
  339. package/build/stores/settings.d.ts.map +1 -1
  340. package/build/stores/settings.js +157 -17
  341. package/build/stores/settings.js.map +1 -1
  342. package/build/types/applet.d.ts +2 -0
  343. package/build/types/applet.d.ts.map +1 -1
  344. package/build/types/applet.js.map +1 -1
  345. package/build/types/asg.d.ts +7 -0
  346. package/build/types/asg.d.ts.map +1 -1
  347. package/build/types/asg.js.map +1 -1
  348. package/build/types/enums.d.ts +2 -25
  349. package/build/types/enums.d.ts.map +1 -1
  350. package/build/types/enums.js +2 -27
  351. package/build/types/enums.js.map +1 -1
  352. package/build/types/hardware.d.ts +4 -13
  353. package/build/types/hardware.d.ts.map +1 -1
  354. package/build/types/hardware.js +15 -3
  355. package/build/types/hardware.js.map +1 -1
  356. package/build/types/index.d.ts +2 -6
  357. package/build/types/index.d.ts.map +1 -1
  358. package/build/types/index.js +2 -6
  359. package/build/types/index.js.map +1 -1
  360. package/build/utils/configuredDevHost.d.ts +6 -0
  361. package/build/utils/configuredDevHost.d.ts.map +1 -0
  362. package/build/utils/configuredDevHost.js +19 -0
  363. package/build/utils/configuredDevHost.js.map +1 -0
  364. package/build/utils/devMiniappLaunch.d.ts +19 -8
  365. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  366. package/build/utils/devMiniappLaunch.js +144 -21
  367. package/build/utils/devMiniappLaunch.js.map +1 -1
  368. package/build/utils/diagnosticContext.d.ts.map +1 -1
  369. package/build/utils/diagnosticContext.js +15 -17
  370. package/build/utils/diagnosticContext.js.map +1 -1
  371. package/build/utils/hardware/hardware.d.ts.map +1 -1
  372. package/build/utils/hardware/hardware.js +7 -3
  373. package/build/utils/hardware/hardware.js.map +1 -1
  374. package/build/utils/miniappDiagnostics.d.ts +64 -0
  375. package/build/utils/miniappDiagnostics.d.ts.map +1 -0
  376. package/build/utils/miniappDiagnostics.js +173 -0
  377. package/build/utils/miniappDiagnostics.js.map +1 -0
  378. package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
  379. package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
  380. package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
  381. package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
  382. package/build/utils/timers/timers.d.ts.map +1 -1
  383. package/build/utils/timers/timers.js +55 -18
  384. package/build/utils/timers/timers.js.map +1 -1
  385. package/package.json +59 -31
  386. package/src/assets/silence.wav +0 -0
  387. package/src/bluetooth-sdk/debug.ts +1 -0
  388. package/src/bluetooth-sdk/index.ts +2 -0
  389. package/src/bluetooth-sdk/photo-receiver.ts +2 -0
  390. package/src/bluetooth-sdk/react.ts +1 -0
  391. package/src/bluetooth-sdk/types.ts +1 -0
  392. package/src/engine.ts +9 -4
  393. package/src/facades/dev.ts +17 -12
  394. package/src/facades/display.ts +1 -1
  395. package/src/facades/gallery.ts +1 -1
  396. package/src/facades/glasses.ts +20 -7
  397. package/src/facades/glassesSettings.ts +5 -0
  398. package/src/facades/miniapps.ts +7 -0
  399. package/src/facades/ota.ts +23 -8
  400. package/src/facades/pairing.ts +15 -11
  401. package/src/facades/permissions.ts +14 -0
  402. package/src/facades/phoneNotifications.ts +4 -13
  403. package/src/facades/speech.ts +21 -7
  404. package/src/generated/releaseMetadata.ts +20 -0
  405. package/src/index.ts +39 -13
  406. package/src/react/MentraLiveOtaFlow.tsx +856 -0
  407. package/src/react/index.ts +7 -0
  408. package/src/react/useEngineSnapshot.ts +16 -0
  409. package/src/runtime/bootstrap.ts +33 -1
  410. package/src/runtime/scanQrSeam.ts +20 -0
  411. package/src/services/AppRegistry.ts +240 -149
  412. package/src/services/AudioCloudUplink.ts +23 -1
  413. package/src/services/AudioPlaybackService.ts +287 -38
  414. package/src/services/BlobStore.ts +22 -9
  415. package/src/services/CloudAudioSubscriptionSync.ts +13 -1
  416. package/src/services/CloudClientService.ts +96 -1
  417. package/src/services/DeviceEventRouter.ts +5 -5
  418. package/src/services/ForegroundLocationPermission.ts +24 -0
  419. package/src/services/GlassesSettingsSync.ts +9 -3
  420. package/src/services/GlassesStatusProjection.ts +16 -8
  421. package/src/services/HotspotOtaTransport.ts +184 -0
  422. package/src/services/HotspotShutdown.ts +41 -0
  423. package/src/services/LocalDisplayManager.ts +112 -21
  424. package/src/services/LocalMiniappRuntime.ts +967 -346
  425. package/src/services/LocalMiniappStorage.ts +82 -0
  426. package/src/services/LocalMiniappUserIdentity.ts +46 -0
  427. package/src/services/LocalSttFallbackCoordinator.ts +19 -12
  428. package/src/services/MicStateCoordinator.ts +169 -4
  429. package/src/services/MiniappLauncher.ts +30 -3
  430. package/src/services/MiniappLiveness.ts +24 -0
  431. package/src/services/NativeHttpResponse.ts +6 -0
  432. package/src/services/OtaArtifactDownloader.ts +312 -0
  433. package/src/services/OtaAutoChain.ts +106 -0
  434. package/src/services/OtaErrorMapping.ts +80 -0
  435. package/src/services/OtaInstallCoordinator.ts +649 -144
  436. package/src/services/OtaService.ts +11 -5
  437. package/src/services/OtaUpdateCheckService.ts +181 -21
  438. package/src/services/PhoneCalendarHelpers.ts +212 -0
  439. package/src/services/PhoneCalendarService.ts +65 -0
  440. package/src/services/PhoneCameraFovCoordinator.ts +210 -0
  441. package/src/services/PhoneNotificationsSync.ts +12 -10
  442. package/src/services/PhonePhotoCoordinator.ts +116 -18
  443. package/src/services/PhoneStreamCoordinator.ts +139 -25
  444. package/src/services/PhoneVideoCoordinator.ts +11 -0
  445. package/src/services/SceneRenderer.ts +16 -0
  446. package/src/services/SentenceTtsPipeline.ts +106 -0
  447. package/src/services/SupportProfileSync.ts +218 -0
  448. package/src/services/TranscriptionRouting.ts +37 -0
  449. package/src/services/TtsTextSanitizer.ts +66 -0
  450. package/src/services/WifiAdbRequest.ts +53 -0
  451. package/src/services/asg/asgCameraApi.ts +615 -33
  452. package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
  453. package/src/services/asg/cameraRollExportLedger.ts +122 -0
  454. package/src/services/asg/galleryNotices.ts +1 -0
  455. package/src/services/asg/galleryPathMigration.ts +22 -0
  456. package/src/services/asg/gallerySettingsService.ts +3 -0
  457. package/src/services/asg/gallerySyncService.ts +184 -73
  458. package/src/services/asg/galleryTransferLedger.ts +312 -0
  459. package/src/services/asg/localNetworkTransport.ts +169 -0
  460. package/src/services/asg/localStorageService.ts +179 -24
  461. package/src/services/asg/mediaProcessingQueue.ts +209 -62
  462. package/src/services/audioPlaybackAssets.ts +8 -0
  463. package/src/services/gallerySyncClock.ts +1 -1
  464. package/src/services/glassesClockSync.ts +6 -2
  465. package/src/services/manifestActions.ts +30 -0
  466. package/src/services/otaDisplayState.ts +58 -17
  467. package/src/services/otaInstallPolicy.ts +30 -4
  468. package/src/services/otaLegacyMapping.ts +1 -1
  469. package/src/services/otaManifestPolicy.ts +42 -0
  470. package/src/services/otaManifestUrl.ts +44 -0
  471. package/src/services/slimStreamStatus.ts +16 -5
  472. package/src/stores/apps.ts +12 -0
  473. package/src/stores/bluetoothSettingKeys.ts +2 -0
  474. package/src/stores/gallerySync.ts +4 -0
  475. package/src/stores/glasses.ts +3 -0
  476. package/src/stores/settings.ts +179 -18
  477. package/src/types/applet.ts +2 -0
  478. package/src/types/asg.ts +7 -0
  479. package/src/types/enums.ts +3 -28
  480. package/src/types/hardware.ts +20 -13
  481. package/src/types/index.ts +2 -6
  482. package/src/utils/configuredDevHost.ts +17 -0
  483. package/src/utils/devMiniappLaunch.ts +151 -23
  484. package/src/utils/diagnosticContext.ts +17 -17
  485. package/src/utils/hardware/hardware.ts +7 -9
  486. package/src/utils/miniappDiagnostics.ts +226 -0
  487. package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
  488. package/src/utils/timers/timers.ts +57 -21
  489. package/build/devtools.d.ts +0 -11
  490. package/build/devtools.d.ts.map +0 -1
  491. package/build/devtools.js +0 -13
  492. package/build/devtools.js.map +0 -1
  493. package/build/internal.d.ts +0 -66
  494. package/build/internal.d.ts.map +0 -1
  495. package/build/internal.js +0 -89
  496. package/build/internal.js.map +0 -1
  497. package/build/services/asgOtaVersionUrl.d.ts +0 -2
  498. package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
  499. package/build/services/asgOtaVersionUrl.js +0 -36
  500. package/build/services/asgOtaVersionUrl.js.map +0 -1
  501. package/src/devtools.ts +0 -13
  502. package/src/internal.ts +0 -158
  503. package/src/services/asgOtaVersionUrl.ts +0 -41
@@ -0,0 +1,64 @@
1
+ import type { ClientApp } from "../types/applet";
2
+ export interface MiniappManifestSnapshot {
3
+ packageName: string;
4
+ name?: string;
5
+ version?: string;
6
+ sdkVersion?: string;
7
+ minHostVersion?: string;
8
+ type?: string;
9
+ entry?: {
10
+ background?: string;
11
+ ui?: string;
12
+ };
13
+ permissions: Array<{
14
+ type: string;
15
+ required?: boolean;
16
+ }>;
17
+ hardwareRequirements: Array<{
18
+ type: string;
19
+ level: string;
20
+ }>;
21
+ actionIds: string[];
22
+ }
23
+ export interface MiniappRuntimeAppSnapshot {
24
+ packageName: string;
25
+ handshakeComplete: boolean;
26
+ subscriptions: string[];
27
+ lastMessageAgeMs: number;
28
+ requestedLocationRate: string | null;
29
+ hasActiveSpeakerStream: boolean;
30
+ manifest?: MiniappManifestSnapshot;
31
+ }
32
+ export interface MiniappRuntimeDiagnosticSnapshot {
33
+ connectedApps: MiniappRuntimeAppSnapshot[];
34
+ subscriptionsByStream: Record<string, string[]>;
35
+ resources: {
36
+ display: Record<string, unknown>;
37
+ camera: Record<string, unknown>;
38
+ video: Record<string, unknown>;
39
+ stream: Record<string, unknown>;
40
+ cameraFov: Record<string, unknown>;
41
+ };
42
+ }
43
+ type ManifestFallback = {
44
+ packageName: string;
45
+ name?: string;
46
+ version?: string;
47
+ type?: string;
48
+ };
49
+ /**
50
+ * Keep the routing/build fields from miniapp.json while excluding arbitrary
51
+ * free-form manifest content from reports. Descriptions, URLs, and unknown
52
+ * extension fields are intentionally omitted.
53
+ */
54
+ export declare function buildMiniappManifestSnapshot(raw: unknown, fallback: ManifestFallback): MiniappManifestSnapshot;
55
+ export declare function buildMiniappDiagnosticContext(input: {
56
+ apps: ClientApp[];
57
+ foregroundedPackage: string | null;
58
+ runtime: MiniappRuntimeDiagnosticSnapshot;
59
+ getLastOpenedAtMs: (app: ClientApp) => number;
60
+ getManifest: (app: ClientApp) => unknown;
61
+ getReleaseIdentity: (app: ClientApp) => unknown;
62
+ }): Record<string, unknown>;
63
+ export {};
64
+ //# sourceMappingURL=miniappDiagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"miniappDiagnostics.d.ts","sourceRoot":"","sources":["../../src/utils/miniappDiagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAA;AAM9C,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE;QACN,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,EAAE,CAAC,EAAE,MAAM,CAAA;KACZ,CAAA;IACD,WAAW,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC,CAAA;IACtD,oBAAoB,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC,CAAA;IAC1D,SAAS,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,sBAAsB,EAAE,OAAO,CAAA;IAC/B,QAAQ,CAAC,EAAE,uBAAuB,CAAA;CACnC;AAED,MAAM,WAAW,gCAAgC;IAC/C,aAAa,EAAE,yBAAyB,EAAE,CAAA;IAC1C,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IAC/C,SAAS,EAAE;QACT,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACnC,CAAA;CACF;AAED,KAAK,gBAAgB,GAAG;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAsDD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,uBAAuB,CAsB9G;AAoBD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,IAAI,EAAE,SAAS,EAAE,CAAA;IACjB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,OAAO,EAAE,gCAAgC,CAAA;IACzC,iBAAiB,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,MAAM,CAAA;IAC7C,WAAW,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,CAAA;IACxC,kBAAkB,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,CAAA;CAChD,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoE1B"}
@@ -0,0 +1,173 @@
1
+ const MAX_DIAGNOSTIC_STRING_LENGTH = 512;
2
+ const MAX_DIAGNOSTIC_LIST_ITEMS = 100;
3
+ const MAX_RECENT_MINIAPPS = 20;
4
+ function boundedString(value) {
5
+ if (typeof value !== "string")
6
+ return undefined;
7
+ const trimmed = value.trim();
8
+ if (!trimmed)
9
+ return undefined;
10
+ return trimmed.slice(0, MAX_DIAGNOSTIC_STRING_LENGTH);
11
+ }
12
+ function recordValue(value) {
13
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
14
+ }
15
+ function diagnosticPermissions(value) {
16
+ if (!Array.isArray(value))
17
+ return [];
18
+ const permissions = [];
19
+ for (const raw of value) {
20
+ if (typeof raw === "string") {
21
+ const type = boundedString(raw);
22
+ if (type)
23
+ permissions.push({ type });
24
+ continue;
25
+ }
26
+ const permission = recordValue(raw);
27
+ const type = boundedString(permission?.type);
28
+ if (!type)
29
+ continue;
30
+ permissions.push({
31
+ type,
32
+ ...(typeof permission?.required === "boolean" ? { required: permission.required } : {}),
33
+ });
34
+ }
35
+ return permissions.slice(0, MAX_DIAGNOSTIC_LIST_ITEMS);
36
+ }
37
+ function diagnosticHardwareRequirements(value) {
38
+ if (!Array.isArray(value))
39
+ return [];
40
+ const requirements = [];
41
+ for (const raw of value) {
42
+ const requirement = recordValue(raw);
43
+ const type = boundedString(requirement?.type);
44
+ const level = boundedString(requirement?.level);
45
+ if (type && level)
46
+ requirements.push({ type, level });
47
+ }
48
+ return requirements.slice(0, MAX_DIAGNOSTIC_LIST_ITEMS);
49
+ }
50
+ function diagnosticActionIds(value) {
51
+ if (!Array.isArray(value))
52
+ return [];
53
+ return value
54
+ .map((raw) => boundedString(typeof raw === "string" ? raw : recordValue(raw)?.id))
55
+ .filter((id) => id !== undefined)
56
+ .sort()
57
+ .slice(0, MAX_DIAGNOSTIC_LIST_ITEMS);
58
+ }
59
+ /**
60
+ * Keep the routing/build fields from miniapp.json while excluding arbitrary
61
+ * free-form manifest content from reports. Descriptions, URLs, and unknown
62
+ * extension fields are intentionally omitted.
63
+ */
64
+ export function buildMiniappManifestSnapshot(raw, fallback) {
65
+ const manifest = recordValue(raw);
66
+ const entry = recordValue(manifest?.entry);
67
+ const packageName = boundedString(manifest?.packageName) ?? boundedString(fallback.packageName) ?? "unknown";
68
+ const name = boundedString(manifest?.name) ?? boundedString(fallback.name);
69
+ const version = boundedString(manifest?.version) ?? boundedString(fallback.version);
70
+ const type = boundedString(manifest?.type) ?? boundedString(fallback.type);
71
+ const background = boundedString(entry?.background);
72
+ const ui = boundedString(entry?.ui);
73
+ return {
74
+ packageName,
75
+ ...(name ? { name } : {}),
76
+ ...(version ? { version } : {}),
77
+ ...(boundedString(manifest?.sdkVersion) ? { sdkVersion: boundedString(manifest?.sdkVersion) } : {}),
78
+ ...(boundedString(manifest?.minHostVersion) ? { minHostVersion: boundedString(manifest?.minHostVersion) } : {}),
79
+ ...(type ? { type } : {}),
80
+ ...(background || ui ? { entry: { ...(background ? { background } : {}), ...(ui ? { ui } : {}) } } : {}),
81
+ permissions: diagnosticPermissions(manifest?.permissions),
82
+ hardwareRequirements: diagnosticHardwareRequirements(manifest?.hardwareRequirements),
83
+ actionIds: diagnosticActionIds(manifest?.actions ?? manifest?.actionIds),
84
+ };
85
+ }
86
+ function executionMode(app) {
87
+ if (app.offline)
88
+ return "built_in";
89
+ if (app.isMiniappDev && app.devUrl && !app.version)
90
+ return "dev_server";
91
+ if (app.isMiniappDev)
92
+ return "dev_snapshot";
93
+ return "installed_bundle";
94
+ }
95
+ function safeReleaseIdentity(value) {
96
+ const identity = recordValue(value);
97
+ if (!identity)
98
+ return undefined;
99
+ const out = {};
100
+ for (const key of ["source", "releaseId", "bundleSha256", "channel"]) {
101
+ const field = boundedString(identity[key]);
102
+ if (field)
103
+ out[key] = field;
104
+ }
105
+ return Object.keys(out).length > 0 ? out : undefined;
106
+ }
107
+ export function buildMiniappDiagnosticContext(input) {
108
+ const runtimeByPackage = new Map(input.runtime.connectedApps.map((app) => [app.packageName, app]));
109
+ const appSnapshots = input.apps.map((app) => {
110
+ const lastOpenedAtMs = input.getLastOpenedAtMs(app);
111
+ const packageName = boundedString(app.packageName) ?? "unknown";
112
+ return {
113
+ packageName,
114
+ name: boundedString(app.name) ?? packageName,
115
+ version: boundedString(app.version) ?? null,
116
+ executionMode: executionMode(app),
117
+ running: app.running,
118
+ foregrounded: app.packageName === input.foregroundedPackage,
119
+ loading: app.loading,
120
+ healthy: app.healthy,
121
+ hidden: app.hidden,
122
+ type: app.type,
123
+ offline: app.offline,
124
+ local: app.local,
125
+ lastOpenedAtMs: Number.isFinite(lastOpenedAtMs) ? lastOpenedAtMs : 0,
126
+ };
127
+ });
128
+ const recentlyInteracted = [...appSnapshots]
129
+ .filter((app) => app.lastOpenedAtMs > 0)
130
+ .sort((a, b) => b.lastOpenedAtMs - a.lastOpenedAtMs)
131
+ .slice(0, MAX_RECENT_MINIAPPS)
132
+ .map((app) => ({ packageName: app.packageName, lastOpenedAtMs: app.lastOpenedAtMs }));
133
+ const runningMiniapps = input.apps
134
+ .filter((app) => app.running)
135
+ .map((app) => {
136
+ const runtime = runtimeByPackage.get(app.packageName);
137
+ const releaseIdentity = safeReleaseIdentity(input.getReleaseIdentity(app));
138
+ const packageName = boundedString(app.packageName) ?? "unknown";
139
+ const manifest = buildMiniappManifestSnapshot(input.getManifest(app) ?? runtime?.manifest, {
140
+ packageName,
141
+ name: app.name,
142
+ version: app.version,
143
+ type: app.type,
144
+ });
145
+ return {
146
+ packageName,
147
+ version: boundedString(app.version) ?? manifest.version ?? null,
148
+ executionMode: executionMode(app),
149
+ foregrounded: app.packageName === input.foregroundedPackage,
150
+ manifest,
151
+ ...(releaseIdentity ? { releaseIdentity } : {}),
152
+ runtime: runtime
153
+ ? {
154
+ handshakeComplete: runtime.handshakeComplete,
155
+ subscriptions: runtime.subscriptions,
156
+ lastMessageAgeMs: runtime.lastMessageAgeMs,
157
+ requestedLocationRate: runtime.requestedLocationRate,
158
+ hasActiveSpeakerStream: runtime.hasActiveSpeakerStream,
159
+ }
160
+ : null,
161
+ };
162
+ });
163
+ return {
164
+ apps: appSnapshots,
165
+ installed: appSnapshots.map((app) => app.packageName),
166
+ running: runningMiniapps.map((app) => app.packageName),
167
+ foregroundedPackage: boundedString(input.foregroundedPackage) ?? null,
168
+ mostRecentlyInteractedPackage: recentlyInteracted[0]?.packageName ?? null,
169
+ recentlyInteracted,
170
+ runningMiniapps,
171
+ };
172
+ }
173
+ //# sourceMappingURL=miniappDiagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"miniappDiagnostics.js","sourceRoot":"","sources":["../../src/utils/miniappDiagnostics.ts"],"names":[],"mappings":"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","sourcesContent":["import type {ClientApp} from \"../types/applet\"\n\nconst MAX_DIAGNOSTIC_STRING_LENGTH = 512\nconst MAX_DIAGNOSTIC_LIST_ITEMS = 100\nconst MAX_RECENT_MINIAPPS = 20\n\nexport interface MiniappManifestSnapshot {\n packageName: string\n name?: string\n version?: string\n sdkVersion?: string\n minHostVersion?: string\n type?: string\n entry?: {\n background?: string\n ui?: string\n }\n permissions: Array<{type: string; required?: boolean}>\n hardwareRequirements: Array<{type: string; level: string}>\n actionIds: string[]\n}\n\nexport interface MiniappRuntimeAppSnapshot {\n packageName: string\n handshakeComplete: boolean\n subscriptions: string[]\n lastMessageAgeMs: number\n requestedLocationRate: string | null\n hasActiveSpeakerStream: boolean\n manifest?: MiniappManifestSnapshot\n}\n\nexport interface MiniappRuntimeDiagnosticSnapshot {\n connectedApps: MiniappRuntimeAppSnapshot[]\n subscriptionsByStream: Record<string, string[]>\n resources: {\n display: Record<string, unknown>\n camera: Record<string, unknown>\n video: Record<string, unknown>\n stream: Record<string, unknown>\n cameraFov: Record<string, unknown>\n }\n}\n\ntype ManifestFallback = {\n packageName: string\n name?: string\n version?: string\n type?: string\n}\n\nfunction boundedString(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined\n const trimmed = value.trim()\n if (!trimmed) return undefined\n return trimmed.slice(0, MAX_DIAGNOSTIC_STRING_LENGTH)\n}\n\nfunction recordValue(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as Record<string, unknown>) : null\n}\n\nfunction diagnosticPermissions(value: unknown): Array<{type: string; required?: boolean}> {\n if (!Array.isArray(value)) return []\n const permissions: Array<{type: string; required?: boolean}> = []\n for (const raw of value) {\n if (typeof raw === \"string\") {\n const type = boundedString(raw)\n if (type) permissions.push({type})\n continue\n }\n const permission = recordValue(raw)\n const type = boundedString(permission?.type)\n if (!type) continue\n permissions.push({\n type,\n ...(typeof permission?.required === \"boolean\" ? {required: permission.required} : {}),\n })\n }\n return permissions.slice(0, MAX_DIAGNOSTIC_LIST_ITEMS)\n}\n\nfunction diagnosticHardwareRequirements(value: unknown): Array<{type: string; level: string}> {\n if (!Array.isArray(value)) return []\n const requirements: Array<{type: string; level: string}> = []\n for (const raw of value) {\n const requirement = recordValue(raw)\n const type = boundedString(requirement?.type)\n const level = boundedString(requirement?.level)\n if (type && level) requirements.push({type, level})\n }\n return requirements.slice(0, MAX_DIAGNOSTIC_LIST_ITEMS)\n}\n\nfunction diagnosticActionIds(value: unknown): string[] {\n if (!Array.isArray(value)) return []\n return value\n .map((raw) => boundedString(typeof raw === \"string\" ? raw : recordValue(raw)?.id))\n .filter((id): id is string => id !== undefined)\n .sort()\n .slice(0, MAX_DIAGNOSTIC_LIST_ITEMS)\n}\n\n/**\n * Keep the routing/build fields from miniapp.json while excluding arbitrary\n * free-form manifest content from reports. Descriptions, URLs, and unknown\n * extension fields are intentionally omitted.\n */\nexport function buildMiniappManifestSnapshot(raw: unknown, fallback: ManifestFallback): MiniappManifestSnapshot {\n const manifest = recordValue(raw)\n const entry = recordValue(manifest?.entry)\n const packageName = boundedString(manifest?.packageName) ?? boundedString(fallback.packageName) ?? \"unknown\"\n const name = boundedString(manifest?.name) ?? boundedString(fallback.name)\n const version = boundedString(manifest?.version) ?? boundedString(fallback.version)\n const type = boundedString(manifest?.type) ?? boundedString(fallback.type)\n const background = boundedString(entry?.background)\n const ui = boundedString(entry?.ui)\n\n return {\n packageName,\n ...(name ? {name} : {}),\n ...(version ? {version} : {}),\n ...(boundedString(manifest?.sdkVersion) ? {sdkVersion: boundedString(manifest?.sdkVersion)} : {}),\n ...(boundedString(manifest?.minHostVersion) ? {minHostVersion: boundedString(manifest?.minHostVersion)} : {}),\n ...(type ? {type} : {}),\n ...(background || ui ? {entry: {...(background ? {background} : {}), ...(ui ? {ui} : {})}} : {}),\n permissions: diagnosticPermissions(manifest?.permissions),\n hardwareRequirements: diagnosticHardwareRequirements(manifest?.hardwareRequirements),\n actionIds: diagnosticActionIds(manifest?.actions ?? manifest?.actionIds),\n }\n}\n\nfunction executionMode(app: ClientApp): \"built_in\" | \"dev_server\" | \"dev_snapshot\" | \"installed_bundle\" {\n if (app.offline) return \"built_in\"\n if (app.isMiniappDev && app.devUrl && !app.version) return \"dev_server\"\n if (app.isMiniappDev) return \"dev_snapshot\"\n return \"installed_bundle\"\n}\n\nfunction safeReleaseIdentity(value: unknown): Record<string, string> | undefined {\n const identity = recordValue(value)\n if (!identity) return undefined\n const out: Record<string, string> = {}\n for (const key of [\"source\", \"releaseId\", \"bundleSha256\", \"channel\"] as const) {\n const field = boundedString(identity[key])\n if (field) out[key] = field\n }\n return Object.keys(out).length > 0 ? out : undefined\n}\n\nexport function buildMiniappDiagnosticContext(input: {\n apps: ClientApp[]\n foregroundedPackage: string | null\n runtime: MiniappRuntimeDiagnosticSnapshot\n getLastOpenedAtMs: (app: ClientApp) => number\n getManifest: (app: ClientApp) => unknown\n getReleaseIdentity: (app: ClientApp) => unknown\n}): Record<string, unknown> {\n const runtimeByPackage = new Map(input.runtime.connectedApps.map((app) => [app.packageName, app]))\n const appSnapshots = input.apps.map((app) => {\n const lastOpenedAtMs = input.getLastOpenedAtMs(app)\n const packageName = boundedString(app.packageName) ?? \"unknown\"\n return {\n packageName,\n name: boundedString(app.name) ?? packageName,\n version: boundedString(app.version) ?? null,\n executionMode: executionMode(app),\n running: app.running,\n foregrounded: app.packageName === input.foregroundedPackage,\n loading: app.loading,\n healthy: app.healthy,\n hidden: app.hidden,\n type: app.type,\n offline: app.offline,\n local: app.local,\n lastOpenedAtMs: Number.isFinite(lastOpenedAtMs) ? lastOpenedAtMs : 0,\n }\n })\n\n const recentlyInteracted = [...appSnapshots]\n .filter((app) => app.lastOpenedAtMs > 0)\n .sort((a, b) => b.lastOpenedAtMs - a.lastOpenedAtMs)\n .slice(0, MAX_RECENT_MINIAPPS)\n .map((app) => ({packageName: app.packageName, lastOpenedAtMs: app.lastOpenedAtMs}))\n\n const runningMiniapps = input.apps\n .filter((app) => app.running)\n .map((app) => {\n const runtime = runtimeByPackage.get(app.packageName)\n const releaseIdentity = safeReleaseIdentity(input.getReleaseIdentity(app))\n const packageName = boundedString(app.packageName) ?? \"unknown\"\n const manifest = buildMiniappManifestSnapshot(input.getManifest(app) ?? runtime?.manifest, {\n packageName,\n name: app.name,\n version: app.version,\n type: app.type,\n })\n return {\n packageName,\n version: boundedString(app.version) ?? manifest.version ?? null,\n executionMode: executionMode(app),\n foregrounded: app.packageName === input.foregroundedPackage,\n manifest,\n ...(releaseIdentity ? {releaseIdentity} : {}),\n runtime: runtime\n ? {\n handshakeComplete: runtime.handshakeComplete,\n subscriptions: runtime.subscriptions,\n lastMessageAgeMs: runtime.lastMessageAgeMs,\n requestedLocationRate: runtime.requestedLocationRate,\n hasActiveSpeakerStream: runtime.hasActiveSpeakerStream,\n }\n : null,\n }\n })\n\n return {\n apps: appSnapshots,\n installed: appSnapshots.map((app) => app.packageName),\n running: runningMiniapps.map((app) => app.packageName),\n foregroundedPackage: boundedString(input.foregroundedPackage) ?? null,\n mostRecentlyInteractedPackage: recentlyInteracted[0]?.packageName ?? null,\n recentlyInteracted,\n runningMiniapps,\n }\n}\n"]}
@@ -1,3 +1,10 @@
1
+ export interface MediaLibrarySaveReceipt {
2
+ success: boolean;
3
+ platform: "ios" | "android" | "unknown";
4
+ uri?: string;
5
+ identifier?: string;
6
+ error?: string;
7
+ }
1
8
  /**
2
9
  * MediaLibraryPermissions - Handles save-only permissions for camera roll
3
10
  *
@@ -7,6 +14,8 @@
7
14
  * - Android 9-: Uses WRITE_EXTERNAL_STORAGE (legacy)
8
15
  */
9
16
  export declare class MediaLibraryPermissions {
17
+ /** Limited iOS access cannot see historical, unselected assets for duplicate reconciliation. */
18
+ static hasLimitedAccess(): Promise<boolean>;
10
19
  /**
11
20
  * Check if we have permission to save to the camera roll
12
21
  * Note: On Android 10+, this always returns true since no permission is needed
@@ -30,5 +39,7 @@ export declare class MediaLibraryPermissions {
30
39
  * @param creationTime - Optional creation/capture time in milliseconds (Unix timestamp)
31
40
  */
32
41
  static saveToLibrary(filePath: string, creationTime?: number): Promise<boolean>;
42
+ /** Save and return the durable MediaStore/PhotoKit identifier used as the export receipt. */
43
+ static saveToLibraryWithReceipt(filePath: string, creationTime?: number): Promise<MediaLibrarySaveReceipt>;
33
44
  }
34
45
  //# sourceMappingURL=MediaLibraryPermissions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibraryPermissions.d.ts","sourceRoot":"","sources":["../../../src/utils/permissions/MediaLibraryPermissions.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,qBAAa,uBAAuB;IAClC;;;OAGG;WACU,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBhD;;;OAGG;WACU,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBlD;;;;;;;;;;;OAWG;WACU,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CA2CtF"}
1
+ {"version":3,"file":"MediaLibraryPermissions.d.ts","sourceRoot":"","sources":["../../../src/utils/permissions/MediaLibraryPermissions.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,SAAS,CAAA;IACvC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;GAOG;AACH,qBAAa,uBAAuB;IAClC,gGAAgG;WACnF,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAWjD;;;OAGG;WACU,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBhD;;;OAGG;WACU,iBAAiB,IAAI,OAAO,CAAC,OAAO,CAAC;IAyBlD;;;;;;;;;;;OAWG;WACU,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrF,6FAA6F;WAChF,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;CAiDjH"}
@@ -11,6 +11,19 @@ import { deriveGalleryDisplayName } from "./galleryDisplayName";
11
11
  * - Android 9-: Uses WRITE_EXTERNAL_STORAGE (legacy)
12
12
  */
13
13
  export class MediaLibraryPermissions {
14
+ /** Limited iOS access cannot see historical, unselected assets for duplicate reconciliation. */
15
+ static async hasLimitedAccess() {
16
+ if (Platform.OS !== "ios")
17
+ return false;
18
+ try {
19
+ return (await check(PERMISSIONS.IOS.PHOTO_LIBRARY)) === RESULTS.LIMITED;
20
+ }
21
+ catch (error) {
22
+ console.error("[MediaLibrary] Error checking limited-library access:", error);
23
+ // Conservatively block legacy reconciliation when the scope cannot be verified.
24
+ return true;
25
+ }
26
+ }
14
27
  /**
15
28
  * Check if we have permission to save to the camera roll
16
29
  * Note: On Android 10+, this always returns true since no permission is needed
@@ -78,6 +91,11 @@ export class MediaLibraryPermissions {
78
91
  * @param creationTime - Optional creation/capture time in milliseconds (Unix timestamp)
79
92
  */
80
93
  static async saveToLibrary(filePath, creationTime) {
94
+ return (await this.saveToLibraryWithReceipt(filePath, creationTime)).success;
95
+ }
96
+ /** Save and return the durable MediaStore/PhotoKit identifier used as the export receipt. */
97
+ static async saveToLibraryWithReceipt(filePath, creationTime) {
98
+ const platform = Platform.OS === "ios" || Platform.OS === "android" ? Platform.OS : "unknown";
81
99
  try {
82
100
  // On Android 10+, we can save without permission
83
101
  // On iOS and older Android, check permission first
@@ -88,7 +106,7 @@ export class MediaLibraryPermissions {
88
106
  const granted = await this.requestPermission();
89
107
  if (!granted) {
90
108
  console.warn("[MediaLibrary] No permission to save to library - photos saved to app storage only");
91
- return false;
109
+ return { success: false, platform, error: "permission denied" };
92
110
  }
93
111
  }
94
112
  }
@@ -106,16 +124,21 @@ export class MediaLibraryPermissions {
106
124
  else {
107
125
  console.log(`[MediaLibrary] Saved to camera roll: ${cleanPath}`);
108
126
  }
109
- return true;
127
+ return {
128
+ success: true,
129
+ platform,
130
+ uri: result.uri,
131
+ identifier: result.identifier,
132
+ };
110
133
  }
111
134
  else {
112
135
  console.error(`[MediaLibrary] Failed to save to library: ${result.error}`);
113
- return false;
136
+ return { success: false, platform, error: result.error || "native export failed" };
114
137
  }
115
138
  }
116
139
  catch (error) {
117
140
  console.error("[MediaLibrary] Error saving to library:", error);
118
- return false;
141
+ return { success: false, platform, error: error instanceof Error ? error.message : String(error) };
119
142
  }
120
143
  }
121
144
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MediaLibraryPermissions.js","sourceRoot":"","sources":["../../../src/utils/permissions/MediaLibraryPermissions.ts"],"names":[],"mappings":"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","sourcesContent":["import {Platform} from \"react-native\"\nimport {check, request, PERMISSIONS, RESULTS} from \"react-native-permissions\"\n\nimport CrustModule from \"@mentra/crust\"\n\nimport {deriveGalleryDisplayName} from \"./galleryDisplayName\"\n\n/**\n * MediaLibraryPermissions - Handles save-only permissions for camera roll\n *\n * Platform behavior:\n * - iOS: Uses PHOTO_LIBRARY (read-write) so we can manage the MentraOS album\n * - Android 10+ (API 29+): No permission needed to save your own files to MediaStore\n * - Android 9-: Uses WRITE_EXTERNAL_STORAGE (legacy)\n */\nexport class MediaLibraryPermissions {\n /**\n * Check if we have permission to save to the camera roll\n * Note: On Android 10+, this always returns true since no permission is needed\n */\n static async checkPermission(): Promise<boolean> {\n try {\n if (Platform.OS === \"ios\") {\n const status = await check(PERMISSIONS.IOS.PHOTO_LIBRARY)\n return status === RESULTS.GRANTED || status === RESULTS.LIMITED\n }\n\n if (Platform.OS === \"android\") {\n // Android 10+ (API 29+): No permission needed to save your own files\n if (Platform.Version >= 29) {\n return true\n }\n // Android 9 and below: Check legacy write permission\n const status = await check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE)\n return status === RESULTS.GRANTED\n }\n\n return false\n } catch (error) {\n console.error(\"[MediaLibrary] Error checking permission:\", error)\n // On error, assume we can try (Android 10+ doesn't need permission anyway)\n return Platform.OS === \"android\" && Platform.Version >= 29\n }\n }\n\n /**\n * Request permission to save to the camera roll\n * Note: On Android 10+, this always returns true since no permission is needed\n */\n static async requestPermission(): Promise<boolean> {\n try {\n if (Platform.OS === \"ios\") {\n const status = await request(PERMISSIONS.IOS.PHOTO_LIBRARY)\n return status === RESULTS.GRANTED || status === RESULTS.LIMITED\n }\n\n if (Platform.OS === \"android\") {\n // Android 10+ (API 29+): No permission needed to save your own files\n if (Platform.Version >= 29) {\n return true\n }\n // Android 9 and below: Request legacy write permission\n const status = await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE)\n return status === RESULTS.GRANTED\n }\n\n return false\n } catch (error) {\n console.error(\"[MediaLibrary] Error requesting permission:\", error)\n // On error, assume we can try (Android 10+ doesn't need permission anyway)\n return Platform.OS === \"android\" && Platform.Version >= 29\n }\n }\n\n /**\n * Save a file to the photo library in a glasses-specific location (MentraOS album on iOS;\n * Pictures/MentraOS or Movies/MentraOS on Android 10+).\n * On Android 10+, this works without any permission.\n *\n * IMPORTANT: This method sets the DATE_TAKEN (Android) or creation date (iOS)\n * metadata to the original capture time, so gallery apps show the correct date.\n * Also saves files in chronological order for proper \"date added\" ordering.\n *\n * @param filePath - Path to the file to save\n * @param creationTime - Optional creation/capture time in milliseconds (Unix timestamp)\n */\n static async saveToLibrary(filePath: string, creationTime?: number): Promise<boolean> {\n try {\n // On Android 10+, we can save without permission\n // On iOS and older Android, check permission first\n if (!(Platform.OS === \"android\" && Platform.Version >= 29)) {\n const hasPermission = await this.checkPermission()\n if (!hasPermission) {\n // Try requesting permission one more time\n const granted = await this.requestPermission()\n if (!granted) {\n console.warn(\"[MediaLibrary] No permission to save to library - photos saved to app storage only\")\n return false\n }\n }\n }\n\n // Remove file:// prefix if present\n const cleanPath = filePath.replace(\"file://\", \"\")\n const displayName = deriveGalleryDisplayName(cleanPath)\n\n // Use native module to save with proper DATE_TAKEN / creation date metadata\n // This ensures gallery apps show the correct capture date, not the sync date\n const result = await CrustModule.saveToGalleryWithDate(cleanPath, creationTime, displayName)\n\n if (result.success) {\n if (creationTime) {\n const captureDate = new Date(creationTime)\n console.log(\n `[MediaLibrary] Saved to camera roll with DATE_TAKEN: ${cleanPath} (captured: ${captureDate.toISOString()})`,\n )\n } else {\n console.log(`[MediaLibrary] Saved to camera roll: ${cleanPath}`)\n }\n return true\n } else {\n console.error(`[MediaLibrary] Failed to save to library: ${result.error}`)\n return false\n }\n } catch (error) {\n console.error(\"[MediaLibrary] Error saving to library:\", error)\n return false\n }\n }\n}\n"]}
1
+ {"version":3,"file":"MediaLibraryPermissions.js","sourceRoot":"","sources":["../../../src/utils/permissions/MediaLibraryPermissions.ts"],"names":[],"mappings":"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","sourcesContent":["import {Platform} from \"react-native\"\nimport {check, request, PERMISSIONS, RESULTS} from \"react-native-permissions\"\n\nimport CrustModule from \"@mentra/crust\"\n\nimport {deriveGalleryDisplayName} from \"./galleryDisplayName\"\n\nexport interface MediaLibrarySaveReceipt {\n success: boolean\n platform: \"ios\" | \"android\" | \"unknown\"\n uri?: string\n identifier?: string\n error?: string\n}\n\n/**\n * MediaLibraryPermissions - Handles save-only permissions for camera roll\n *\n * Platform behavior:\n * - iOS: Uses PHOTO_LIBRARY (read-write) so we can manage the MentraOS album\n * - Android 10+ (API 29+): No permission needed to save your own files to MediaStore\n * - Android 9-: Uses WRITE_EXTERNAL_STORAGE (legacy)\n */\nexport class MediaLibraryPermissions {\n /** Limited iOS access cannot see historical, unselected assets for duplicate reconciliation. */\n static async hasLimitedAccess(): Promise<boolean> {\n if (Platform.OS !== \"ios\") return false\n try {\n return (await check(PERMISSIONS.IOS.PHOTO_LIBRARY)) === RESULTS.LIMITED\n } catch (error) {\n console.error(\"[MediaLibrary] Error checking limited-library access:\", error)\n // Conservatively block legacy reconciliation when the scope cannot be verified.\n return true\n }\n }\n\n /**\n * Check if we have permission to save to the camera roll\n * Note: On Android 10+, this always returns true since no permission is needed\n */\n static async checkPermission(): Promise<boolean> {\n try {\n if (Platform.OS === \"ios\") {\n const status = await check(PERMISSIONS.IOS.PHOTO_LIBRARY)\n return status === RESULTS.GRANTED || status === RESULTS.LIMITED\n }\n\n if (Platform.OS === \"android\") {\n // Android 10+ (API 29+): No permission needed to save your own files\n if (Platform.Version >= 29) {\n return true\n }\n // Android 9 and below: Check legacy write permission\n const status = await check(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE)\n return status === RESULTS.GRANTED\n }\n\n return false\n } catch (error) {\n console.error(\"[MediaLibrary] Error checking permission:\", error)\n // On error, assume we can try (Android 10+ doesn't need permission anyway)\n return Platform.OS === \"android\" && Platform.Version >= 29\n }\n }\n\n /**\n * Request permission to save to the camera roll\n * Note: On Android 10+, this always returns true since no permission is needed\n */\n static async requestPermission(): Promise<boolean> {\n try {\n if (Platform.OS === \"ios\") {\n const status = await request(PERMISSIONS.IOS.PHOTO_LIBRARY)\n return status === RESULTS.GRANTED || status === RESULTS.LIMITED\n }\n\n if (Platform.OS === \"android\") {\n // Android 10+ (API 29+): No permission needed to save your own files\n if (Platform.Version >= 29) {\n return true\n }\n // Android 9 and below: Request legacy write permission\n const status = await request(PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE)\n return status === RESULTS.GRANTED\n }\n\n return false\n } catch (error) {\n console.error(\"[MediaLibrary] Error requesting permission:\", error)\n // On error, assume we can try (Android 10+ doesn't need permission anyway)\n return Platform.OS === \"android\" && Platform.Version >= 29\n }\n }\n\n /**\n * Save a file to the photo library in a glasses-specific location (MentraOS album on iOS;\n * Pictures/MentraOS or Movies/MentraOS on Android 10+).\n * On Android 10+, this works without any permission.\n *\n * IMPORTANT: This method sets the DATE_TAKEN (Android) or creation date (iOS)\n * metadata to the original capture time, so gallery apps show the correct date.\n * Also saves files in chronological order for proper \"date added\" ordering.\n *\n * @param filePath - Path to the file to save\n * @param creationTime - Optional creation/capture time in milliseconds (Unix timestamp)\n */\n static async saveToLibrary(filePath: string, creationTime?: number): Promise<boolean> {\n return (await this.saveToLibraryWithReceipt(filePath, creationTime)).success\n }\n\n /** Save and return the durable MediaStore/PhotoKit identifier used as the export receipt. */\n static async saveToLibraryWithReceipt(filePath: string, creationTime?: number): Promise<MediaLibrarySaveReceipt> {\n const platform = Platform.OS === \"ios\" || Platform.OS === \"android\" ? Platform.OS : \"unknown\"\n try {\n // On Android 10+, we can save without permission\n // On iOS and older Android, check permission first\n if (!(Platform.OS === \"android\" && Platform.Version >= 29)) {\n const hasPermission = await this.checkPermission()\n if (!hasPermission) {\n // Try requesting permission one more time\n const granted = await this.requestPermission()\n if (!granted) {\n console.warn(\"[MediaLibrary] No permission to save to library - photos saved to app storage only\")\n return {success: false, platform, error: \"permission denied\"}\n }\n }\n }\n\n // Remove file:// prefix if present\n const cleanPath = filePath.replace(\"file://\", \"\")\n const displayName = deriveGalleryDisplayName(cleanPath)\n\n // Use native module to save with proper DATE_TAKEN / creation date metadata\n // This ensures gallery apps show the correct capture date, not the sync date\n const result = await CrustModule.saveToGalleryWithDate(cleanPath, creationTime, displayName)\n\n if (result.success) {\n if (creationTime) {\n const captureDate = new Date(creationTime)\n console.log(\n `[MediaLibrary] Saved to camera roll with DATE_TAKEN: ${cleanPath} (captured: ${captureDate.toISOString()})`,\n )\n } else {\n console.log(`[MediaLibrary] Saved to camera roll: ${cleanPath}`)\n }\n return {\n success: true,\n platform,\n uri: result.uri,\n identifier: result.identifier,\n }\n } else {\n console.error(`[MediaLibrary] Failed to save to library: ${result.error}`)\n return {success: false, platform, error: result.error || \"native export failed\"}\n }\n } catch (error) {\n console.error(\"[MediaLibrary] Error saving to library:\", error)\n return {success: false, platform, error: error instanceof Error ? error.message : String(error)}\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"AAoFA,qBAAa,OAAO;IAClB,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO/D,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAO9C,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO9D,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAM7C;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAU/G;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAY/G"}
1
+ {"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"AAwHA,qBAAa,OAAO;IAClB,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO/D,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAO9C,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO9D,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAM7C;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAU/G;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAY/G"}
@@ -1,27 +1,63 @@
1
- // until https://github.com/tconns/react-native-nitro-bg-timer/issues/2 is resolved, we need to use this class to disable this package on iOS:
2
- import { Platform } from "react-native";
1
+ // BgTimer — background-safe timers for the engine.
2
+ //
3
+ // Everything timing-critical in the engine runs through this class: the
4
+ // miniapp liveness watchdog, display durationMs expiries, boot windows,
5
+ // auth-token refresh. On Android, React Native PAUSES plain JS timers while
6
+ // the app is backgrounded, so those features only keep working in the
7
+ // background when the native implementation (react-native-nitro-bg-timer)
8
+ // is active.
9
+ //
10
+ // Who actually gets native timers:
11
+ // - Android, dev AND release: always attempted — dev must match production
12
+ // background behavior. There is no opt-in/opt-out env var. If the native
13
+ // module is unavailable (a dev client whose binary predates it, or a
14
+ // broken release binary), the failure is LOUD: a console.error with the
15
+ // remediation, plus a blocking dev alert. The JS-timer fallback still
16
+ // engages so foreground behavior keeps working, but backgrounded
17
+ // behavior is broken until the native rebuild — the error says exactly
18
+ // that. (A silent dev fallback previously cost a full debugging day of
19
+ // phantom "zombie miniapp" bugs; see OS-1790.)
20
+ // - iOS: never, dev or prod — the package is disabled pending
21
+ // https://github.com/tconns/react-native-nitro-bg-timer/issues/2. iOS
22
+ // suspends the whole process in background anyway, so background timing
23
+ // there is handled by native per-device queues, not JS timers.
24
+ import { Alert, Platform } from "react-native";
3
25
  let nitroTimer;
4
26
  let nitroDisabled = false;
5
- let warnedUnavailable = false;
6
- function warnUnavailable(reason) {
7
- if (warnedUnavailable) {
27
+ let failedLoud = false;
28
+ /**
29
+ * The native background timer is unavailable — say so ONCE, loudly, with the
30
+ * remediation. The JS-timer fallback keeps foreground behavior working, but
31
+ * everything timing-driven freezes while the app is backgrounded, which
32
+ * presents as phantom miniapp bugs (frozen captions, missed wake words,
33
+ * watchdog kills on resume). A quiet warning here has already cost a full
34
+ * debugging day; never downgrade this to console.warn.
35
+ */
36
+ function failUnavailable(reason) {
37
+ if (failedLoud) {
8
38
  return;
9
39
  }
10
- warnedUnavailable = true;
11
- console.warn(`BgTimer: ${reason}, using JS timers`);
40
+ failedLoud = true;
41
+ const message = `BgTimer: native background timer unavailable (${reason}). ` +
42
+ "Backgrounded behavior IS BROKEN until you rebuild the Android app: run `bun android`. " +
43
+ "Engine timers and local miniapps (captions, wake words) freeze whenever the app is not foregrounded.";
44
+ console.error(message);
45
+ if (__DEV__) {
46
+ // A stale dev client may ALSO show the library's own require-time red box
47
+ // (bridgeless LogBox surfaces it even though we catch below) — this alert
48
+ // is the actionable one: it names the fix.
49
+ try {
50
+ Alert.alert("Background timers unavailable", message);
51
+ }
52
+ catch {
53
+ /* Alert not available (tests / headless) — the console.error stands. */
54
+ }
55
+ }
12
56
  }
13
57
  function getNitroTimer() {
14
58
  if (nitroDisabled || Platform.OS !== "android") {
15
59
  return null;
16
60
  }
17
- // react-native-nitro-bg-timer calls createHybridObject() at require() time. On dev
18
- // builds with a stale native binary that throws NPE, React Native still surfaces a
19
- // red LogBox error even when the exception is caught. Skip nitro in __DEV__ unless
20
- // explicitly enabled after a native rebuild (bun android).
21
- if (__DEV__ && process.env.EXPO_PUBLIC_USE_NITRO_BG_TIMER !== "true") {
22
- warnUnavailable("nitro bg-timer disabled in dev (set EXPO_PUBLIC_USE_NITRO_BG_TIMER=true after native rebuild)");
23
- return null;
24
- }
25
61
  if (nitroTimer !== undefined) {
26
62
  return nitroTimer;
27
63
  }
@@ -29,7 +65,7 @@ function getNitroTimer() {
29
65
  const { isRuntimeAlive } = require("react-native-nitro-modules");
30
66
  if (typeof isRuntimeAlive === "function" && !isRuntimeAlive()) {
31
67
  nitroTimer = null;
32
- warnUnavailable("nitro runtime is not alive");
68
+ failUnavailable("nitro runtime is not alive");
33
69
  return nitroTimer;
34
70
  }
35
71
  const { BackgroundTimer } = require("react-native-nitro-bg-timer");
@@ -47,7 +83,7 @@ function getNitroTimer() {
47
83
  nitroDisabled = true;
48
84
  }
49
85
  if (!nitroTimer) {
50
- warnUnavailable("react-native-nitro-bg-timer unavailable");
86
+ failUnavailable("react-native-nitro-bg-timer failed to load");
51
87
  }
52
88
  return nitroTimer;
53
89
  }
@@ -62,7 +98,8 @@ function withNitro(run, fallback) {
62
98
  catch (error) {
63
99
  nitroDisabled = true;
64
100
  nitroTimer = null;
65
- console.warn("BgTimer: nitro timer failed, using JS timers", error);
101
+ failedLoud = false; // a mid-session failure is new information — re-announce
102
+ failUnavailable(`nitro timer call threw: ${String(error)}`);
66
103
  return fallback();
67
104
  }
68
105
  }
@@ -1 +1 @@
1
- {"version":3,"file":"timers.js","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"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","sourcesContent":["// until https://github.com/tconns/react-native-nitro-bg-timer/issues/2 is resolved, we need to use this class to disable this package on iOS:\n\nimport {Platform} from \"react-native\"\n\ntype NitroTimerApi = {\n setInterval: (callback: () => void, delay: number) => number\n clearInterval: (intervalId: number) => void\n setTimeout: (callback: () => void, delay: number) => number\n clearTimeout: (timeoutId: number) => void\n}\n\nlet nitroTimer: NitroTimerApi | null | undefined\nlet nitroDisabled = false\nlet warnedUnavailable = false\n\nfunction warnUnavailable(reason: string) {\n if (warnedUnavailable) {\n return\n }\n warnedUnavailable = true\n console.warn(`BgTimer: ${reason}, using JS timers`)\n}\n\nfunction getNitroTimer(): NitroTimerApi | null {\n if (nitroDisabled || Platform.OS !== \"android\") {\n return null\n }\n\n // react-native-nitro-bg-timer calls createHybridObject() at require() time. On dev\n // builds with a stale native binary that throws NPE, React Native still surfaces a\n // red LogBox error even when the exception is caught. Skip nitro in __DEV__ unless\n // explicitly enabled after a native rebuild (bun android).\n if (__DEV__ && process.env.EXPO_PUBLIC_USE_NITRO_BG_TIMER !== \"true\") {\n warnUnavailable(\"nitro bg-timer disabled in dev (set EXPO_PUBLIC_USE_NITRO_BG_TIMER=true after native rebuild)\")\n return null\n }\n\n if (nitroTimer !== undefined) {\n return nitroTimer\n }\n\n try {\n const {isRuntimeAlive} = require(\"react-native-nitro-modules\") as {isRuntimeAlive?: () => boolean}\n if (typeof isRuntimeAlive === \"function\" && !isRuntimeAlive()) {\n nitroTimer = null\n warnUnavailable(\"nitro runtime is not alive\")\n return nitroTimer\n }\n\n const {BackgroundTimer} = require(\"react-native-nitro-bg-timer\") as {BackgroundTimer?: NitroTimerApi}\n nitroTimer =\n BackgroundTimer &&\n typeof BackgroundTimer.setTimeout === \"function\" &&\n typeof BackgroundTimer.setInterval === \"function\" &&\n typeof BackgroundTimer.clearTimeout === \"function\" &&\n typeof BackgroundTimer.clearInterval === \"function\"\n ? BackgroundTimer\n : null\n } catch {\n nitroTimer = null\n nitroDisabled = true\n }\n\n if (!nitroTimer) {\n warnUnavailable(\"react-native-nitro-bg-timer unavailable\")\n }\n return nitroTimer\n}\n\nfunction withNitro<T>(run: (api: NitroTimerApi) => T, fallback: () => T): T {\n const api = getNitroTimer()\n if (!api) {\n return fallback()\n }\n try {\n return run(api)\n } catch (error) {\n nitroDisabled = true\n nitroTimer = null\n console.warn(\"BgTimer: nitro timer failed, using JS timers\", error)\n return fallback()\n }\n}\n\nexport class BgTimer {\n static setInterval(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setInterval(callback, delay),\n () => setInterval(callback, delay) as unknown as number,\n )\n }\n\n static clearInterval(intervalId: number): void {\n withNitro(\n (api) => api.clearInterval(intervalId),\n () => clearInterval(intervalId),\n )\n }\n\n static setTimeout(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setTimeout(callback, delay),\n () => setTimeout(callback, delay) as unknown as number,\n )\n }\n\n static clearTimeout(timeoutId: number): void {\n withNitro(\n (api) => api.clearTimeout(timeoutId),\n () => clearTimeout(timeoutId),\n )\n }\n}\n\nexport function throttle<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let lastCalled = 0\n\n return (...args: Parameters<T>) => {\n const now = Date.now()\n if (now - lastCalled >= ms) {\n lastCalled = now\n fn(...args)\n }\n }\n}\n\nexport function debounce<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let timeoutId: number | null = null\n\n return (...args: Parameters<T>) => {\n if (timeoutId) {\n BgTimer.clearTimeout(timeoutId)\n }\n timeoutId = BgTimer.setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, ms)\n }\n}\n"]}
1
+ {"version":3,"file":"timers.js","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,wEAAwE;AACxE,wEAAwE;AACxE,4EAA4E;AAC5E,sEAAsE;AACtE,0EAA0E;AAC1E,aAAa;AACb,EAAE;AACF,mCAAmC;AACnC,6EAA6E;AAC7E,6EAA6E;AAC7E,yEAAyE;AACzE,4EAA4E;AAC5E,0EAA0E;AAC1E,qEAAqE;AACrE,2EAA2E;AAC3E,2EAA2E;AAC3E,mDAAmD;AACnD,gEAAgE;AAChE,0EAA0E;AAC1E,4EAA4E;AAC5E,mEAAmE;AAEnE,OAAO,EAAC,KAAK,EAAE,QAAQ,EAAC,MAAM,cAAc,CAAA;AAS5C,IAAI,UAA4C,CAAA;AAChD,IAAI,aAAa,GAAG,KAAK,CAAA;AACzB,IAAI,UAAU,GAAG,KAAK,CAAA;AAEtB;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,MAAc;IACrC,IAAI,UAAU,EAAE,CAAC;QACf,OAAM;IACR,CAAC;IACD,UAAU,GAAG,IAAI,CAAA;IACjB,MAAM,OAAO,GACX,iDAAiD,MAAM,KAAK;QAC5D,wFAAwF;QACxF,sGAAsG,CAAA;IACxG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACtB,IAAI,OAAO,EAAE,CAAC;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,2CAA2C;QAC3C,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,CAAC,+BAA+B,EAAE,OAAO,CAAC,CAAA;QACvD,CAAC;QAAC,MAAM,CAAC;YACP,wEAAwE;QAC1E,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,aAAa,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,EAAC,cAAc,EAAC,GAAG,OAAO,CAAC,4BAA4B,CAAqC,CAAA;QAClG,IAAI,OAAO,cAAc,KAAK,UAAU,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC9D,UAAU,GAAG,IAAI,CAAA;YACjB,eAAe,CAAC,4BAA4B,CAAC,CAAA;YAC7C,OAAO,UAAU,CAAA;QACnB,CAAC;QAED,MAAM,EAAC,eAAe,EAAC,GAAG,OAAO,CAAC,6BAA6B,CAAsC,CAAA;QACrG,UAAU;YACR,eAAe;gBACf,OAAO,eAAe,CAAC,UAAU,KAAK,UAAU;gBAChD,OAAO,eAAe,CAAC,WAAW,KAAK,UAAU;gBACjD,OAAO,eAAe,CAAC,YAAY,KAAK,UAAU;gBAClD,OAAO,eAAe,CAAC,aAAa,KAAK,UAAU;gBACjD,CAAC,CAAC,eAAe;gBACjB,CAAC,CAAC,IAAI,CAAA;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAA;QACjB,aAAa,GAAG,IAAI,CAAA;IACtB,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,eAAe,CAAC,4CAA4C,CAAC,CAAA;IAC/D,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,SAAS,SAAS,CAAI,GAA8B,EAAE,QAAiB;IACrE,MAAM,GAAG,GAAG,aAAa,EAAE,CAAA;IAC3B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,QAAQ,EAAE,CAAA;IACnB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,aAAa,GAAG,IAAI,CAAA;QACpB,UAAU,GAAG,IAAI,CAAA;QACjB,UAAU,GAAG,KAAK,CAAA,CAAC,yDAAyD;QAC5E,eAAe,CAAC,2BAA2B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3D,OAAO,QAAQ,EAAE,CAAA;IACnB,CAAC;AACH,CAAC;AAED,MAAM,OAAO,OAAO;IAClB,MAAM,CAAC,WAAW,CAAC,QAAoB,EAAE,KAAa;QACpD,OAAO,SAAS,CACd,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,EACzC,GAAG,EAAE,CAAC,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAsB,CACxD,CAAA;IACH,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,UAAkB;QACrC,SAAS,CACP,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,EACtC,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAChC,CAAA;IACH,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,QAAoB,EAAE,KAAa;QACnD,OAAO,SAAS,CACd,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,EACxC,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAsB,CACvD,CAAA;IACH,CAAC;IAED,MAAM,CAAC,YAAY,CAAC,SAAiB;QACnC,SAAS,CACP,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,EACpC,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAC9B,CAAA;IACH,CAAC;CACF;AAED,MAAM,UAAU,QAAQ,CAAoC,EAAK,EAAE,EAAU;IAC3E,IAAI,UAAU,GAAG,CAAC,CAAA;IAElB,OAAO,CAAC,GAAG,IAAmB,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,IAAI,GAAG,GAAG,UAAU,IAAI,EAAE,EAAE,CAAC;YAC3B,UAAU,GAAG,GAAG,CAAA;YAChB,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QACb,CAAC;IACH,CAAC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAoC,EAAK,EAAE,EAAU;IAC3E,IAAI,SAAS,GAAkB,IAAI,CAAA;IAEnC,OAAO,CAAC,GAAG,IAAmB,EAAE,EAAE;QAChC,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAA;QACjC,CAAC;QACD,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;YAClC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;YACX,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC,CAAA;AACH,CAAC","sourcesContent":["// BgTimer — background-safe timers for the engine.\n//\n// Everything timing-critical in the engine runs through this class: the\n// miniapp liveness watchdog, display durationMs expiries, boot windows,\n// auth-token refresh. On Android, React Native PAUSES plain JS timers while\n// the app is backgrounded, so those features only keep working in the\n// background when the native implementation (react-native-nitro-bg-timer)\n// is active.\n//\n// Who actually gets native timers:\n// - Android, dev AND release: always attempted — dev must match production\n// background behavior. There is no opt-in/opt-out env var. If the native\n// module is unavailable (a dev client whose binary predates it, or a\n// broken release binary), the failure is LOUD: a console.error with the\n// remediation, plus a blocking dev alert. The JS-timer fallback still\n// engages so foreground behavior keeps working, but backgrounded\n// behavior is broken until the native rebuild — the error says exactly\n// that. (A silent dev fallback previously cost a full debugging day of\n// phantom \"zombie miniapp\" bugs; see OS-1790.)\n// - iOS: never, dev or prod — the package is disabled pending\n// https://github.com/tconns/react-native-nitro-bg-timer/issues/2. iOS\n// suspends the whole process in background anyway, so background timing\n// there is handled by native per-device queues, not JS timers.\n\nimport {Alert, Platform} from \"react-native\"\n\ntype NitroTimerApi = {\n setInterval: (callback: () => void, delay: number) => number\n clearInterval: (intervalId: number) => void\n setTimeout: (callback: () => void, delay: number) => number\n clearTimeout: (timeoutId: number) => void\n}\n\nlet nitroTimer: NitroTimerApi | null | undefined\nlet nitroDisabled = false\nlet failedLoud = false\n\n/**\n * The native background timer is unavailable — say so ONCE, loudly, with the\n * remediation. The JS-timer fallback keeps foreground behavior working, but\n * everything timing-driven freezes while the app is backgrounded, which\n * presents as phantom miniapp bugs (frozen captions, missed wake words,\n * watchdog kills on resume). A quiet warning here has already cost a full\n * debugging day; never downgrade this to console.warn.\n */\nfunction failUnavailable(reason: string) {\n if (failedLoud) {\n return\n }\n failedLoud = true\n const message =\n `BgTimer: native background timer unavailable (${reason}). ` +\n \"Backgrounded behavior IS BROKEN until you rebuild the Android app: run `bun android`. \" +\n \"Engine timers and local miniapps (captions, wake words) freeze whenever the app is not foregrounded.\"\n console.error(message)\n if (__DEV__) {\n // A stale dev client may ALSO show the library's own require-time red box\n // (bridgeless LogBox surfaces it even though we catch below) — this alert\n // is the actionable one: it names the fix.\n try {\n Alert.alert(\"Background timers unavailable\", message)\n } catch {\n /* Alert not available (tests / headless) the console.error stands. */\n }\n }\n}\n\nfunction getNitroTimer(): NitroTimerApi | null {\n if (nitroDisabled || Platform.OS !== \"android\") {\n return null\n }\n\n if (nitroTimer !== undefined) {\n return nitroTimer\n }\n\n try {\n const {isRuntimeAlive} = require(\"react-native-nitro-modules\") as {isRuntimeAlive?: () => boolean}\n if (typeof isRuntimeAlive === \"function\" && !isRuntimeAlive()) {\n nitroTimer = null\n failUnavailable(\"nitro runtime is not alive\")\n return nitroTimer\n }\n\n const {BackgroundTimer} = require(\"react-native-nitro-bg-timer\") as {BackgroundTimer?: NitroTimerApi}\n nitroTimer =\n BackgroundTimer &&\n typeof BackgroundTimer.setTimeout === \"function\" &&\n typeof BackgroundTimer.setInterval === \"function\" &&\n typeof BackgroundTimer.clearTimeout === \"function\" &&\n typeof BackgroundTimer.clearInterval === \"function\"\n ? BackgroundTimer\n : null\n } catch {\n nitroTimer = null\n nitroDisabled = true\n }\n\n if (!nitroTimer) {\n failUnavailable(\"react-native-nitro-bg-timer failed to load\")\n }\n return nitroTimer\n}\n\nfunction withNitro<T>(run: (api: NitroTimerApi) => T, fallback: () => T): T {\n const api = getNitroTimer()\n if (!api) {\n return fallback()\n }\n try {\n return run(api)\n } catch (error) {\n nitroDisabled = true\n nitroTimer = null\n failedLoud = false // a mid-session failure is new information — re-announce\n failUnavailable(`nitro timer call threw: ${String(error)}`)\n return fallback()\n }\n}\n\nexport class BgTimer {\n static setInterval(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setInterval(callback, delay),\n () => setInterval(callback, delay) as unknown as number,\n )\n }\n\n static clearInterval(intervalId: number): void {\n withNitro(\n (api) => api.clearInterval(intervalId),\n () => clearInterval(intervalId),\n )\n }\n\n static setTimeout(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setTimeout(callback, delay),\n () => setTimeout(callback, delay) as unknown as number,\n )\n }\n\n static clearTimeout(timeoutId: number): void {\n withNitro(\n (api) => api.clearTimeout(timeoutId),\n () => clearTimeout(timeoutId),\n )\n }\n}\n\nexport function throttle<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let lastCalled = 0\n\n return (...args: Parameters<T>) => {\n const now = Date.now()\n if (now - lastCalled >= ms) {\n lastCalled = now\n fn(...args)\n }\n }\n}\n\nexport function debounce<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let timeoutId: number | null = null\n\n return (...args: Parameters<T>) => {\n if (timeoutId) {\n BgTimer.clearTimeout(timeoutId)\n }\n timeoutId = BgTimer.setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, ms)\n }\n}\n"]}