@mentra/engine 0.1.0-dev.0 → 3.1.0-dev.4
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.
- package/README.md +55 -18
- package/build/bluetooth-sdk/debug.d.ts +2 -0
- package/build/bluetooth-sdk/debug.d.ts.map +1 -0
- package/build/bluetooth-sdk/debug.js +2 -0
- package/build/bluetooth-sdk/debug.js.map +1 -0
- package/build/bluetooth-sdk/index.d.ts +3 -0
- package/build/bluetooth-sdk/index.d.ts.map +1 -0
- package/build/bluetooth-sdk/index.js +3 -0
- package/build/bluetooth-sdk/index.js.map +1 -0
- package/build/bluetooth-sdk/photo-receiver.d.ts +3 -0
- package/build/bluetooth-sdk/photo-receiver.d.ts.map +1 -0
- package/build/bluetooth-sdk/photo-receiver.js +3 -0
- package/build/bluetooth-sdk/photo-receiver.js.map +1 -0
- package/build/bluetooth-sdk/react.d.ts +2 -0
- package/build/bluetooth-sdk/react.d.ts.map +1 -0
- package/build/bluetooth-sdk/react.js +2 -0
- package/build/bluetooth-sdk/react.js.map +1 -0
- package/build/bluetooth-sdk/types.d.ts +2 -0
- package/build/bluetooth-sdk/types.d.ts.map +1 -0
- package/build/bluetooth-sdk/types.js +2 -0
- package/build/bluetooth-sdk/types.js.map +1 -0
- package/build/engine.d.ts +24 -16
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +9 -4
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +3 -2
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +18 -12
- package/build/facades/dev.js.map +1 -1
- package/build/facades/display.d.ts +1 -1
- package/build/facades/display.d.ts.map +1 -1
- package/build/facades/display.js +1 -1
- package/build/facades/display.js.map +1 -1
- package/build/facades/gallery.js +1 -1
- package/build/facades/gallery.js.map +1 -1
- package/build/facades/glasses.d.ts +4 -13
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +21 -6
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/glassesSettings.d.ts.map +1 -1
- package/build/facades/glassesSettings.js +1 -0
- package/build/facades/glassesSettings.js.map +1 -1
- package/build/facades/miniapps.d.ts +4 -0
- package/build/facades/miniapps.d.ts.map +1 -1
- package/build/facades/miniapps.js +5 -0
- package/build/facades/miniapps.js.map +1 -1
- package/build/facades/ota.d.ts +14 -16
- package/build/facades/ota.d.ts.map +1 -1
- package/build/facades/ota.js +22 -7
- package/build/facades/ota.js.map +1 -1
- package/build/facades/pairing.d.ts +8 -5
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +12 -10
- package/build/facades/pairing.js.map +1 -1
- package/build/facades/permissions.d.ts +10 -0
- package/build/facades/permissions.d.ts.map +1 -1
- package/build/facades/permissions.js +10 -0
- package/build/facades/permissions.js.map +1 -1
- package/build/facades/phoneNotifications.d.ts +0 -4
- package/build/facades/phoneNotifications.d.ts.map +1 -1
- package/build/facades/phoneNotifications.js +4 -14
- package/build/facades/phoneNotifications.js.map +1 -1
- package/build/facades/speech.d.ts +7 -6
- package/build/facades/speech.d.ts.map +1 -1
- package/build/facades/speech.js +1 -1
- package/build/facades/speech.js.map +1 -1
- package/build/generated/releaseMetadata.d.ts +12 -0
- package/build/generated/releaseMetadata.d.ts.map +1 -0
- package/build/generated/releaseMetadata.js +10 -0
- package/build/generated/releaseMetadata.js.map +1 -0
- package/build/index.d.ts +10 -8
- package/build/index.d.ts.map +1 -1
- package/build/index.js +6 -5
- package/build/index.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.d.ts +38 -0
- package/build/react/MentraLiveOtaFlow.d.ts.map +1 -0
- package/build/react/MentraLiveOtaFlow.js +528 -0
- package/build/react/MentraLiveOtaFlow.js.map +1 -0
- package/build/react/index.d.ts +2 -0
- package/build/react/index.d.ts.map +1 -0
- package/build/react/index.js +2 -0
- package/build/react/index.js.map +1 -0
- package/build/react/useEngineSnapshot.d.ts +2 -0
- package/build/react/useEngineSnapshot.d.ts.map +1 -0
- package/build/react/useEngineSnapshot.js +14 -0
- package/build/react/useEngineSnapshot.js.map +1 -0
- package/build/runtime/bootstrap.d.ts +24 -1
- package/build/runtime/bootstrap.d.ts.map +1 -1
- package/build/runtime/bootstrap.js +17 -0
- package/build/runtime/bootstrap.js.map +1 -1
- package/build/runtime/scanQrSeam.d.ts +7 -0
- package/build/runtime/scanQrSeam.d.ts.map +1 -0
- package/build/runtime/scanQrSeam.js +16 -0
- package/build/runtime/scanQrSeam.js.map +1 -0
- package/build/services/AppRegistry.d.ts +41 -57
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +208 -144
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/AudioCloudUplink.d.ts +12 -0
- package/build/services/AudioCloudUplink.d.ts.map +1 -1
- package/build/services/AudioCloudUplink.js +22 -1
- package/build/services/AudioCloudUplink.js.map +1 -1
- package/build/services/AudioPlaybackService.d.ts +41 -2
- package/build/services/AudioPlaybackService.d.ts.map +1 -1
- package/build/services/AudioPlaybackService.js +250 -33
- package/build/services/AudioPlaybackService.js.map +1 -1
- package/build/services/BlobStore.d.ts +2 -1
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +17 -9
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -1
- package/build/services/CloudAudioSubscriptionSync.js +13 -1
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -1
- package/build/services/CloudClientService.d.ts +15 -0
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +93 -1
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DeviceEventRouter.js +5 -5
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/ForegroundLocationPermission.d.ts +13 -0
- package/build/services/ForegroundLocationPermission.d.ts.map +1 -0
- package/build/services/ForegroundLocationPermission.js +12 -0
- package/build/services/ForegroundLocationPermission.js.map +1 -0
- package/build/services/GlassesSettingsSync.d.ts.map +1 -1
- package/build/services/GlassesSettingsSync.js +9 -3
- package/build/services/GlassesSettingsSync.js.map +1 -1
- package/build/services/GlassesStatusProjection.d.ts +2 -1
- package/build/services/GlassesStatusProjection.d.ts.map +1 -1
- package/build/services/GlassesStatusProjection.js +15 -8
- package/build/services/GlassesStatusProjection.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts +29 -0
- package/build/services/HotspotOtaTransport.d.ts.map +1 -0
- package/build/services/HotspotOtaTransport.js +146 -0
- package/build/services/HotspotOtaTransport.js.map +1 -0
- package/build/services/HotspotShutdown.d.ts +17 -0
- package/build/services/HotspotShutdown.d.ts.map +1 -0
- package/build/services/HotspotShutdown.js +29 -0
- package/build/services/HotspotShutdown.js.map +1 -0
- package/build/services/LocalDisplayManager.d.ts +15 -0
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +106 -20
- package/build/services/LocalDisplayManager.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +74 -2
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +785 -291
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalMiniappStorage.d.ts +32 -0
- package/build/services/LocalMiniappStorage.d.ts.map +1 -0
- package/build/services/LocalMiniappStorage.js +66 -0
- package/build/services/LocalMiniappStorage.js.map +1 -0
- package/build/services/LocalMiniappUserIdentity.d.ts +20 -0
- package/build/services/LocalMiniappUserIdentity.d.ts.map +1 -0
- package/build/services/LocalMiniappUserIdentity.js +43 -0
- package/build/services/LocalMiniappUserIdentity.js.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts +9 -6
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +18 -12
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/MicStateCoordinator.d.ts +42 -1
- package/build/services/MicStateCoordinator.d.ts.map +1 -1
- package/build/services/MicStateCoordinator.js +141 -3
- package/build/services/MicStateCoordinator.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +23 -3
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MiniappLiveness.d.ts +12 -0
- package/build/services/MiniappLiveness.d.ts.map +1 -0
- package/build/services/MiniappLiveness.js +16 -0
- package/build/services/MiniappLiveness.js.map +1 -0
- package/build/services/NativeHttpResponse.d.ts +3 -0
- package/build/services/NativeHttpResponse.d.ts.map +1 -0
- package/build/services/NativeHttpResponse.js +6 -0
- package/build/services/NativeHttpResponse.js.map +1 -0
- package/build/services/OtaArtifactDownloader.d.ts +65 -0
- package/build/services/OtaArtifactDownloader.d.ts.map +1 -0
- package/build/services/OtaArtifactDownloader.js +226 -0
- package/build/services/OtaArtifactDownloader.js.map +1 -0
- package/build/services/OtaAutoChain.d.ts +34 -0
- package/build/services/OtaAutoChain.d.ts.map +1 -0
- package/build/services/OtaAutoChain.js +83 -0
- package/build/services/OtaAutoChain.js.map +1 -0
- package/build/services/OtaErrorMapping.d.ts +18 -0
- package/build/services/OtaErrorMapping.d.ts.map +1 -0
- package/build/services/OtaErrorMapping.js +63 -0
- package/build/services/OtaErrorMapping.js.map +1 -0
- package/build/services/OtaInstallCoordinator.d.ts +95 -15
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +577 -130
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/OtaService.d.ts.map +1 -1
- package/build/services/OtaService.js +8 -1
- package/build/services/OtaService.js.map +1 -1
- package/build/services/OtaUpdateCheckService.d.ts +39 -4
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
- package/build/services/OtaUpdateCheckService.js +138 -22
- package/build/services/OtaUpdateCheckService.js.map +1 -1
- package/build/services/PhoneCalendarHelpers.d.ts +32 -0
- package/build/services/PhoneCalendarHelpers.d.ts.map +1 -0
- package/build/services/PhoneCalendarHelpers.js +157 -0
- package/build/services/PhoneCalendarHelpers.js.map +1 -0
- package/build/services/PhoneCalendarService.d.ts +5 -0
- package/build/services/PhoneCalendarService.d.ts.map +1 -0
- package/build/services/PhoneCalendarService.js +45 -0
- package/build/services/PhoneCalendarService.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts +30 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.js +194 -0
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +12 -10
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts +26 -2
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
- package/build/services/PhonePhotoCoordinator.js +79 -9
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts +8 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js +125 -13
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/PhoneVideoCoordinator.d.ts +2 -0
- package/build/services/PhoneVideoCoordinator.d.ts.map +1 -1
- package/build/services/PhoneVideoCoordinator.js +10 -0
- package/build/services/PhoneVideoCoordinator.js.map +1 -1
- package/build/services/SceneRenderer.d.ts.map +1 -1
- package/build/services/SceneRenderer.js +15 -0
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/SentenceTtsPipeline.d.ts +31 -0
- package/build/services/SentenceTtsPipeline.d.ts.map +1 -0
- package/build/services/SentenceTtsPipeline.js +67 -0
- package/build/services/SentenceTtsPipeline.js.map +1 -0
- package/build/services/SupportProfileSync.d.ts +22 -0
- package/build/services/SupportProfileSync.d.ts.map +1 -0
- package/build/services/SupportProfileSync.js +213 -0
- package/build/services/SupportProfileSync.js.map +1 -0
- package/build/services/TranscriptionRouting.d.ts +12 -0
- package/build/services/TranscriptionRouting.d.ts.map +1 -0
- package/build/services/TranscriptionRouting.js +24 -0
- package/build/services/TranscriptionRouting.js.map +1 -0
- package/build/services/TtsTextSanitizer.d.ts +5 -0
- package/build/services/TtsTextSanitizer.d.ts.map +1 -0
- package/build/services/TtsTextSanitizer.js +61 -0
- package/build/services/TtsTextSanitizer.js.map +1 -0
- package/build/services/WifiAdbRequest.d.ts +17 -0
- package/build/services/WifiAdbRequest.d.ts.map +1 -0
- package/build/services/WifiAdbRequest.js +35 -0
- package/build/services/WifiAdbRequest.js.map +1 -0
- package/build/services/asg/asgCameraApi.d.ts +43 -0
- package/build/services/asg/asgCameraApi.d.ts.map +1 -1
- package/build/services/asg/asgCameraApi.js +509 -26
- package/build/services/asg/asgCameraApi.js.map +1 -1
- package/build/services/asg/cameraRollExportCoordinator.d.ts +60 -0
- package/build/services/asg/cameraRollExportCoordinator.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportCoordinator.js +618 -0
- package/build/services/asg/cameraRollExportCoordinator.js.map +1 -0
- package/build/services/asg/cameraRollExportLedger.d.ts +44 -0
- package/build/services/asg/cameraRollExportLedger.d.ts.map +1 -0
- package/build/services/asg/cameraRollExportLedger.js +78 -0
- package/build/services/asg/cameraRollExportLedger.js.map +1 -0
- package/build/services/asg/galleryNotices.d.ts +1 -1
- package/build/services/asg/galleryNotices.d.ts.map +1 -1
- package/build/services/asg/galleryNotices.js.map +1 -1
- package/build/services/asg/galleryPathMigration.d.ts +3 -0
- package/build/services/asg/galleryPathMigration.d.ts.map +1 -0
- package/build/services/asg/galleryPathMigration.js +26 -0
- package/build/services/asg/galleryPathMigration.js.map +1 -0
- package/build/services/asg/gallerySettingsService.d.ts +1 -0
- package/build/services/asg/gallerySettingsService.d.ts.map +1 -1
- package/build/services/asg/gallerySettingsService.js +2 -0
- package/build/services/asg/gallerySettingsService.js.map +1 -1
- package/build/services/asg/gallerySyncService.d.ts.map +1 -1
- package/build/services/asg/gallerySyncService.js +162 -56
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/services/asg/galleryTransferLedger.d.ts +58 -0
- package/build/services/asg/galleryTransferLedger.d.ts.map +1 -0
- package/build/services/asg/galleryTransferLedger.js +225 -0
- package/build/services/asg/galleryTransferLedger.js.map +1 -0
- package/build/services/asg/localNetworkTransport.d.ts +15 -0
- package/build/services/asg/localNetworkTransport.d.ts.map +1 -0
- package/build/services/asg/localNetworkTransport.js +144 -0
- package/build/services/asg/localNetworkTransport.js.map +1 -0
- package/build/services/asg/localStorageService.d.ts +18 -0
- package/build/services/asg/localStorageService.d.ts.map +1 -1
- package/build/services/asg/localStorageService.js +168 -19
- package/build/services/asg/localStorageService.js.map +1 -1
- package/build/services/asg/mediaProcessingQueue.d.ts +10 -0
- package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -1
- package/build/services/asg/mediaProcessingQueue.js +193 -62
- package/build/services/asg/mediaProcessingQueue.js.map +1 -1
- package/build/services/audioPlaybackAssets.d.ts +8 -0
- package/build/services/audioPlaybackAssets.d.ts.map +1 -0
- package/build/services/audioPlaybackAssets.js +7 -0
- package/build/services/audioPlaybackAssets.js.map +1 -0
- package/build/services/gallerySyncClock.js +1 -1
- package/build/services/gallerySyncClock.js.map +1 -1
- package/build/services/glassesClockSync.d.ts.map +1 -1
- package/build/services/glassesClockSync.js +6 -2
- package/build/services/glassesClockSync.js.map +1 -1
- package/build/services/manifestActions.d.ts +7 -0
- package/build/services/manifestActions.d.ts.map +1 -0
- package/build/services/manifestActions.js +25 -0
- package/build/services/manifestActions.js.map +1 -0
- package/build/services/otaDisplayState.d.ts +23 -12
- package/build/services/otaDisplayState.d.ts.map +1 -1
- package/build/services/otaDisplayState.js +36 -14
- package/build/services/otaDisplayState.js.map +1 -1
- package/build/services/otaInstallPolicy.d.ts +16 -4
- package/build/services/otaInstallPolicy.d.ts.map +1 -1
- package/build/services/otaInstallPolicy.js +24 -3
- package/build/services/otaInstallPolicy.js.map +1 -1
- package/build/services/otaLegacyMapping.d.ts +1 -1
- package/build/services/otaLegacyMapping.d.ts.map +1 -1
- package/build/services/otaLegacyMapping.js.map +1 -1
- package/build/services/otaManifestPolicy.d.ts +14 -0
- package/build/services/otaManifestPolicy.d.ts.map +1 -0
- package/build/services/otaManifestPolicy.js +19 -0
- package/build/services/otaManifestPolicy.js.map +1 -0
- package/build/services/otaManifestUrl.d.ts +3 -0
- package/build/services/otaManifestUrl.d.ts.map +1 -0
- package/build/services/otaManifestUrl.js +38 -0
- package/build/services/otaManifestUrl.js.map +1 -0
- package/build/services/slimStreamStatus.d.ts +11 -0
- package/build/services/slimStreamStatus.d.ts.map +1 -1
- package/build/services/slimStreamStatus.js +14 -4
- package/build/services/slimStreamStatus.js.map +1 -1
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +11 -0
- package/build/stores/apps.js.map +1 -1
- package/build/stores/bluetoothSettingKeys.d.ts.map +1 -1
- package/build/stores/bluetoothSettingKeys.js +2 -0
- package/build/stores/bluetoothSettingKeys.js.map +1 -1
- package/build/stores/gallerySync.d.ts +2 -0
- package/build/stores/gallerySync.d.ts.map +1 -1
- package/build/stores/gallerySync.js +2 -0
- package/build/stores/gallerySync.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +3 -0
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts +17 -0
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +157 -17
- package/build/stores/settings.js.map +1 -1
- package/build/types/applet.d.ts +2 -0
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/build/types/asg.d.ts +7 -0
- package/build/types/asg.d.ts.map +1 -1
- package/build/types/asg.js.map +1 -1
- package/build/types/enums.d.ts +2 -25
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +2 -27
- package/build/types/enums.js.map +1 -1
- package/build/types/hardware.d.ts +4 -13
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +15 -3
- package/build/types/hardware.js.map +1 -1
- package/build/types/index.d.ts +2 -6
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js +2 -6
- package/build/types/index.js.map +1 -1
- package/build/utils/configuredDevHost.d.ts +6 -0
- package/build/utils/configuredDevHost.d.ts.map +1 -0
- package/build/utils/configuredDevHost.js +19 -0
- package/build/utils/configuredDevHost.js.map +1 -0
- package/build/utils/devMiniappLaunch.d.ts +19 -8
- package/build/utils/devMiniappLaunch.d.ts.map +1 -1
- package/build/utils/devMiniappLaunch.js +144 -21
- package/build/utils/devMiniappLaunch.js.map +1 -1
- package/build/utils/diagnosticContext.d.ts.map +1 -1
- package/build/utils/diagnosticContext.js +15 -17
- package/build/utils/diagnosticContext.js.map +1 -1
- package/build/utils/hardware/hardware.d.ts.map +1 -1
- package/build/utils/hardware/hardware.js +7 -3
- package/build/utils/hardware/hardware.js.map +1 -1
- package/build/utils/miniappDiagnostics.d.ts +64 -0
- package/build/utils/miniappDiagnostics.d.ts.map +1 -0
- package/build/utils/miniappDiagnostics.js +173 -0
- package/build/utils/miniappDiagnostics.js.map +1 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts +11 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -1
- package/build/utils/permissions/MediaLibraryPermissions.js +27 -4
- package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -1
- package/build/utils/timers/timers.d.ts.map +1 -1
- package/build/utils/timers/timers.js +55 -18
- package/build/utils/timers/timers.js.map +1 -1
- package/package.json +59 -31
- package/src/assets/silence.wav +0 -0
- package/src/bluetooth-sdk/debug.ts +1 -0
- package/src/bluetooth-sdk/index.ts +2 -0
- package/src/bluetooth-sdk/photo-receiver.ts +2 -0
- package/src/bluetooth-sdk/react.ts +1 -0
- package/src/bluetooth-sdk/types.ts +1 -0
- package/src/engine.ts +9 -4
- package/src/facades/dev.ts +17 -12
- package/src/facades/display.ts +1 -1
- package/src/facades/gallery.ts +1 -1
- package/src/facades/glasses.ts +20 -7
- package/src/facades/glassesSettings.ts +5 -0
- package/src/facades/miniapps.ts +7 -0
- package/src/facades/ota.ts +23 -8
- package/src/facades/pairing.ts +15 -11
- package/src/facades/permissions.ts +14 -0
- package/src/facades/phoneNotifications.ts +4 -13
- package/src/facades/speech.ts +21 -7
- package/src/generated/releaseMetadata.ts +20 -0
- package/src/index.ts +39 -13
- package/src/react/MentraLiveOtaFlow.tsx +856 -0
- package/src/react/index.ts +7 -0
- package/src/react/useEngineSnapshot.ts +16 -0
- package/src/runtime/bootstrap.ts +33 -1
- package/src/runtime/scanQrSeam.ts +20 -0
- package/src/services/AppRegistry.ts +240 -149
- package/src/services/AudioCloudUplink.ts +23 -1
- package/src/services/AudioPlaybackService.ts +287 -38
- package/src/services/BlobStore.ts +22 -9
- package/src/services/CloudAudioSubscriptionSync.ts +13 -1
- package/src/services/CloudClientService.ts +96 -1
- package/src/services/DeviceEventRouter.ts +5 -5
- package/src/services/ForegroundLocationPermission.ts +24 -0
- package/src/services/GlassesSettingsSync.ts +9 -3
- package/src/services/GlassesStatusProjection.ts +16 -8
- package/src/services/HotspotOtaTransport.ts +184 -0
- package/src/services/HotspotShutdown.ts +41 -0
- package/src/services/LocalDisplayManager.ts +112 -21
- package/src/services/LocalMiniappRuntime.ts +967 -346
- package/src/services/LocalMiniappStorage.ts +82 -0
- package/src/services/LocalMiniappUserIdentity.ts +46 -0
- package/src/services/LocalSttFallbackCoordinator.ts +19 -12
- package/src/services/MicStateCoordinator.ts +169 -4
- package/src/services/MiniappLauncher.ts +30 -3
- package/src/services/MiniappLiveness.ts +24 -0
- package/src/services/NativeHttpResponse.ts +6 -0
- package/src/services/OtaArtifactDownloader.ts +312 -0
- package/src/services/OtaAutoChain.ts +106 -0
- package/src/services/OtaErrorMapping.ts +80 -0
- package/src/services/OtaInstallCoordinator.ts +649 -144
- package/src/services/OtaService.ts +11 -5
- package/src/services/OtaUpdateCheckService.ts +181 -21
- package/src/services/PhoneCalendarHelpers.ts +212 -0
- package/src/services/PhoneCalendarService.ts +65 -0
- package/src/services/PhoneCameraFovCoordinator.ts +210 -0
- package/src/services/PhoneNotificationsSync.ts +12 -10
- package/src/services/PhonePhotoCoordinator.ts +116 -18
- package/src/services/PhoneStreamCoordinator.ts +139 -25
- package/src/services/PhoneVideoCoordinator.ts +11 -0
- package/src/services/SceneRenderer.ts +16 -0
- package/src/services/SentenceTtsPipeline.ts +106 -0
- package/src/services/SupportProfileSync.ts +218 -0
- package/src/services/TranscriptionRouting.ts +37 -0
- package/src/services/TtsTextSanitizer.ts +66 -0
- package/src/services/WifiAdbRequest.ts +53 -0
- package/src/services/asg/asgCameraApi.ts +615 -33
- package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
- package/src/services/asg/cameraRollExportLedger.ts +122 -0
- package/src/services/asg/galleryNotices.ts +1 -0
- package/src/services/asg/galleryPathMigration.ts +22 -0
- package/src/services/asg/gallerySettingsService.ts +3 -0
- package/src/services/asg/gallerySyncService.ts +184 -73
- package/src/services/asg/galleryTransferLedger.ts +312 -0
- package/src/services/asg/localNetworkTransport.ts +169 -0
- package/src/services/asg/localStorageService.ts +179 -24
- package/src/services/asg/mediaProcessingQueue.ts +209 -62
- package/src/services/audioPlaybackAssets.ts +8 -0
- package/src/services/gallerySyncClock.ts +1 -1
- package/src/services/glassesClockSync.ts +6 -2
- package/src/services/manifestActions.ts +30 -0
- package/src/services/otaDisplayState.ts +58 -17
- package/src/services/otaInstallPolicy.ts +30 -4
- package/src/services/otaLegacyMapping.ts +1 -1
- package/src/services/otaManifestPolicy.ts +42 -0
- package/src/services/otaManifestUrl.ts +44 -0
- package/src/services/slimStreamStatus.ts +16 -5
- package/src/stores/apps.ts +12 -0
- package/src/stores/bluetoothSettingKeys.ts +2 -0
- package/src/stores/gallerySync.ts +4 -0
- package/src/stores/glasses.ts +3 -0
- package/src/stores/settings.ts +179 -18
- package/src/types/applet.ts +2 -0
- package/src/types/asg.ts +7 -0
- package/src/types/enums.ts +3 -28
- package/src/types/hardware.ts +20 -13
- package/src/types/index.ts +2 -6
- package/src/utils/configuredDevHost.ts +17 -0
- package/src/utils/devMiniappLaunch.ts +151 -23
- package/src/utils/diagnosticContext.ts +17 -17
- package/src/utils/hardware/hardware.ts +7 -9
- package/src/utils/miniappDiagnostics.ts +226 -0
- package/src/utils/permissions/MediaLibraryPermissions.ts +35 -4
- package/src/utils/timers/timers.ts +57 -21
- package/build/devtools.d.ts +0 -11
- package/build/devtools.d.ts.map +0 -1
- package/build/devtools.js +0 -13
- package/build/devtools.js.map +0 -1
- package/build/internal.d.ts +0 -66
- package/build/internal.d.ts.map +0 -1
- package/build/internal.js +0 -89
- package/build/internal.js.map +0 -1
- package/build/services/asgOtaVersionUrl.d.ts +0 -2
- package/build/services/asgOtaVersionUrl.d.ts.map +0 -1
- package/build/services/asgOtaVersionUrl.js +0 -36
- package/build/services/asgOtaVersionUrl.js.map +0 -1
- package/src/devtools.ts +0 -13
- package/src/internal.ts +0 -158
- package/src/services/asgOtaVersionUrl.ts +0 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../src/types/hardware.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../src/types/hardware.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAiKtC;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAiC;IACjE,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,eAAe;IAC5C,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,eAAe;IAC5C,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,aAAa;IACxC,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,UAAU;IAClC,CAAC,gBAAgB,CAAC,SAAS,CAAC,EAAE,gBAAgB;IAC9C,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,SAAS;IAChC,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,mDAAmD;IACnF,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;QAClB,GAAG,eAAe;QAClB,SAAS,EAAE,WAAW,CAAC,IAAI;QAC3B,OAAO,EAAE;YACP,GAAG,eAAe,CAAC,OAAO;YAC1B,gBAAgB,EAAE,KAAK;SACxB;QACD,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE;YACV,KAAK,EAAE,CAAC;YACR,MAAM,EAAE,KAAK;SACd;KACF;IACD,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,UAAuB,EAAgB,EAAE;IAC5E,MAAM,SAAS,GAAG,UAAoB,CAAC;IACvC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,OAAO,qBAAqB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,qBAAqB,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,iCAAiC;AACjC,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC","sourcesContent":["/** Hardware capability types used by the Engine. */\n\nimport { evenRealitiesG1 } from \"./capabilities/even-realities-g1\";\nimport { evenRealitiesG2 } from \"./capabilities/even-realities-g2\";\nimport { mentraDisplay } from \"./capabilities/mentra-display\";\nimport { mentraLive } from \"./capabilities/mentra-live\";\nimport { simulatedGlasses } from \"./capabilities/simulated-glasses\";\nimport { vuzixZ100 } from \"./capabilities/vuzix-z100\";\nimport { none } from \"./capabilities/none\";\nimport { DeviceTypes } from \"./enums\";\n\nexport type { HardwareRequirement } from \"@mentra/miniapp/hardware\";\n\n/**\n * Camera capabilities\n */\nexport interface CameraCapabilities {\n resolution?: { width: number; height: number };\n hasHDR?: boolean;\n hasFocus?: boolean;\n video: {\n canRecord: boolean;\n canStream: boolean;\n supportedStreamTypes?: string[];\n supportedResolutions?: { width: number; height: number }[];\n };\n}\n\n/**\n * Display capabilities\n */\nexport interface DisplayCapabilities {\n count?: number;\n isColor?: boolean;\n color?: string; // e.g., \"green\", \"full_color\", \"pallet\"\n canDisplayBitmap?: boolean;\n resolution?: { width: number; height: number };\n fieldOfView?: { horizontal?: number; vertical?: number };\n maxTextLines?: number;\n adjustBrightness?: boolean;\n\n // --- Scene display API (display.render()) — typed capabilities ---\n // Pure DATA the host scene pipeline acts on generically; a device without\n // canPosition renders scenes via the host degrade path instead.\n /** Public drawable canvas in px — the raw coordinate space for render() boxes. */\n width?: number;\n height?: number;\n /** True ⇒ the device renders positioned elements (containers / canvas components). */\n canPosition?: boolean;\n /** Element budgets. Rects share the text pool on container-based devices. */\n maxTextElements?: number;\n maxImageElements?: number;\n /** Per-image dimension cap (box-level), when the firmware has one. */\n maxImagePx?: { width: number; height: number };\n shapes?: \"rect\"[];\n intensityLevels?: number;\n partialUpdate?: boolean;\n}\n\n/**\n * Microphone capabilities\n */\nexport interface MicrophoneCapabilities {\n count?: number;\n hasVAD?: boolean; // Voice Activity Detection\n}\n\n/**\n * Speaker capabilities\n */\nexport interface SpeakerCapabilities {\n count?: number;\n isPrivate?: boolean; // e.g., bone conduction\n}\n\n/**\n * IMU (Inertial Measurement Unit) capabilities\n */\nexport interface IMUCapabilities {\n axisCount?: number;\n hasAccelerometer?: boolean;\n hasCompass?: boolean;\n hasGyroscope?: boolean;\n}\n\n/**\n * Button capabilities\n */\nexport interface ButtonCapabilities {\n count?: number;\n buttons?: {\n type: \"press\" | \"swipe1d\" | \"swipe2d\";\n events: string[]; // e.g., \"press\", \"double_press\", \"long_press\", \"swipe_up\", \"swipe_down\"\n isCapacitive?: boolean;\n }[];\n}\n\n/**\n * Light capabilities\n */\nexport interface LightCapabilities {\n count?: number;\n lights?: {\n id: string; // Unique identifier for the LED (e.g., \"privacy\", \"user_feedback\")\n purpose: \"privacy\" | \"user_feedback\" | \"general\"; // LED purpose/function\n isFullColor: boolean;\n color?: string; // e.g., \"white\", \"rgb\"\n position?: \"front_facing\" | \"user_facing\" | \"side\" | \"unknown\"; // LED physical position\n }[];\n}\n\n/**\n * Power capabilities\n */\nexport interface PowerCapabilities {\n hasExternalBattery: boolean; // e.g., a case or puck\n}\n\n/**\n * Device hardware capabilities\n * Complete information about what hardware a device has\n */\nexport interface Capabilities {\n modelName: string;\n\n // Camera capabilities\n hasCamera: boolean;\n camera: CameraCapabilities | null;\n\n // Display capabilities\n hasDisplay: boolean;\n display: DisplayCapabilities | null;\n\n // Microphone capabilities\n hasMicrophone: boolean;\n microphone: MicrophoneCapabilities | null;\n\n // Speaker capabilities\n hasSpeaker: boolean;\n speaker: SpeakerCapabilities | null;\n\n // IMU capabilities\n hasIMU: boolean;\n imu: IMUCapabilities | null;\n\n // Button capabilities\n hasButton: boolean;\n button: ButtonCapabilities | null;\n\n // Light capabilities\n hasLight: boolean;\n light: LightCapabilities | null;\n\n // Power capabilities\n power: PowerCapabilities;\n\n // WiFi capability\n hasWifi: boolean;\n\n // OTA capability\n hasOta?: boolean;\n\n // Native dashboard capability\n // True when the device renders its own dashboard in firmware (e.g. Even\n // Realities' built-in dashboard on G2). MentraOS does not manage or expose\n // dashboard settings for these devices. Absent/false means MentraOS owns the\n // dashboard.\n hasNativeDashboard?: boolean;\n}\n\n/**\n * Hardware capability profiles for supported glasses models\n * Key: model_name string (e.g., \"Even Realities G1\", \"Mentra Live\")\n * Value: Capabilities object defining device features\n */\nexport const HARDWARE_CAPABILITIES: Record<string, Capabilities> = {\n [evenRealitiesG1.modelName]: evenRealitiesG1,\n [evenRealitiesG2.modelName]: evenRealitiesG2,\n [mentraDisplay.modelName]: mentraDisplay,\n [mentraLive.modelName]: mentraLive,\n [simulatedGlasses.modelName]: simulatedGlasses,\n [vuzixZ100.modelName]: vuzixZ100,\n [DeviceTypes.MACH1]: vuzixZ100, // Mach1 uses same Vuzix Ultralite hardware as Z100\n [DeviceTypes.AR99]: {\n ...evenRealitiesG1,\n modelName: DeviceTypes.AR99,\n display: {\n ...evenRealitiesG1.display,\n canDisplayBitmap: false,\n },\n hasMicrophone: true,\n hasOta: true,\n microphone: {\n count: 1,\n hasVAD: false,\n },\n },\n [none.modelName]: none,\n};\n\nexport const getModelCapabilities = (deviceType: DeviceTypes): Capabilities => {\n const modelName = deviceType as string;\n if (!HARDWARE_CAPABILITIES[modelName]) {\n return HARDWARE_CAPABILITIES[DeviceTypes.NONE];\n }\n return HARDWARE_CAPABILITIES[modelName];\n};\n\n// export * from \"./capabilities\"\nexport { simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, vuzixZ100, mentraDisplay };\n"]}
|
package/build/types/index.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* self-contained. Keep these in sync with cloud/packages/types/src when the
|
|
4
|
-
* canonical types change. The capability profiles also live here under
|
|
5
|
-
* ./capabilities/.
|
|
6
|
-
*/
|
|
1
|
+
/** Engine capability types and profiles. Miniapp manifest requirement types
|
|
2
|
+
* are re-exported from @mentra/miniapp, their canonical owner. */
|
|
7
3
|
export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes } from "./enums";
|
|
8
4
|
export type { HardwareRequirement, CameraCapabilities, DisplayCapabilities, MicrophoneCapabilities, SpeakerCapabilities, IMUCapabilities, ButtonCapabilities, LightCapabilities, PowerCapabilities, Capabilities, } from "./hardware";
|
|
9
5
|
export { HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, vuzixZ100, mentraDisplay, } from "./hardware";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;kEACkE;AAGlE,OAAO,EAAC,YAAY,EAAE,wBAAwB,EAAE,WAAW,EAAE,eAAe,EAAC,MAAM,SAAS,CAAA;AAG5F,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,GACb,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAA;AAGnB,YAAY,EAAC,UAAU,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAC,MAAM,UAAU,CAAA"}
|
package/build/types/index.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* self-contained. Keep these in sync with cloud/packages/types/src when the
|
|
4
|
-
* canonical types change. The capability profiles also live here under
|
|
5
|
-
* ./capabilities/.
|
|
6
|
-
*/
|
|
1
|
+
/** Engine capability types and profiles. Miniapp manifest requirement types
|
|
2
|
+
* are re-exported from @mentra/miniapp, their canonical owner. */
|
|
7
3
|
// Enums (runtime values)
|
|
8
4
|
export { HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes } from "./enums";
|
|
9
5
|
export { HARDWARE_CAPABILITIES, getModelCapabilities, simulatedGlasses, evenRealitiesG1, evenRealitiesG2, mentraLive, vuzixZ100, mentraDisplay, } from "./hardware";
|
package/build/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;kEACkE;AAElE,yBAAyB;AACzB,OAAO,EAAC,YAAY,EAAE,wBAAwB,EAAE,WAAW,EAAE,eAAe,EAAC,MAAM,SAAS,CAAA;AAgB5F,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,YAAY,CAAA","sourcesContent":["/** Engine capability types and profiles. Miniapp manifest requirement types\n * are re-exported from @mentra/miniapp, their canonical owner. */\n\n// Enums (runtime values)\nexport {HardwareType, HardwareRequirementLevel, DeviceTypes, ControllerTypes} from \"./enums\"\n\n// Hardware types\nexport type {\n HardwareRequirement,\n CameraCapabilities,\n DisplayCapabilities,\n MicrophoneCapabilities,\n SpeakerCapabilities,\n IMUCapabilities,\n ButtonCapabilities,\n LightCapabilities,\n PowerCapabilities,\n Capabilities,\n} from \"./hardware\"\n\nexport {\n HARDWARE_CAPABILITIES,\n getModelCapabilities,\n simulatedGlasses,\n evenRealitiesG1,\n evenRealitiesG2,\n mentraLive,\n vuzixZ100,\n mentraDisplay,\n} from \"./hardware\"\n\n// Applet types\nexport type {AppletType, AppPermissionType, AppletPermission, AppletInterface, ClientApp} from \"./applet\"\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Explicit Metro / laptop host override used by stale-URL rewrite and launch
|
|
3
|
+
* failover. One source of truth so AppRegistry and decideDevLaunchRoute stay aligned.
|
|
4
|
+
*/
|
|
5
|
+
export declare function configuredDevHost(): string | undefined;
|
|
6
|
+
//# sourceMappingURL=configuredDevHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuredDevHost.d.ts","sourceRoot":"","sources":["../../src/utils/configuredDevHost.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,SAAS,CAUtD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getConfigValues } from "../runtime/bootstrap";
|
|
2
|
+
/**
|
|
3
|
+
* Explicit Metro / laptop host override used by stale-URL rewrite and launch
|
|
4
|
+
* failover. One source of truth so AppRegistry and decideDevLaunchRoute stay aligned.
|
|
5
|
+
*/
|
|
6
|
+
export function configuredDevHost() {
|
|
7
|
+
const explicit = process.env.EXPO_PUBLIC_LOCAL_MINIAPP_HOST;
|
|
8
|
+
if (explicit) {
|
|
9
|
+
try {
|
|
10
|
+
return new URL(explicit).hostname;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
if (/^[\w.-]+$/.test(explicit))
|
|
14
|
+
return explicit;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return getConfigValues().devServerHost?.();
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=configuredDevHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuredDevHost.js","sourceRoot":"","sources":["../../src/utils/configuredDevHost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAA;AAEpD;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAA;IAC3D,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAA;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,OAAO,QAAQ,CAAA;QACjD,CAAC;IACH,CAAC;IACD,OAAO,eAAe,EAAE,CAAC,aAAa,EAAE,EAAE,CAAA;AAC5C,CAAC","sourcesContent":["import {getConfigValues} from \"../runtime/bootstrap\"\n\n/**\n * Explicit Metro / laptop host override used by stale-URL rewrite and launch\n * failover. One source of truth so AppRegistry and decideDevLaunchRoute stay aligned.\n */\nexport function configuredDevHost(): string | undefined {\n const explicit = process.env.EXPO_PUBLIC_LOCAL_MINIAPP_HOST\n if (explicit) {\n try {\n return new URL(explicit).hostname\n } catch {\n if (/^[\\w.-]+$/.test(explicit)) return explicit\n }\n }\n return getConfigValues().devServerHost?.()\n}\n"]}
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
* get it in the same round trip — no second fetch.
|
|
13
13
|
*
|
|
14
14
|
* Pre-flighting at the call site keeps /applet/local a pure mount route.
|
|
15
|
+
*
|
|
16
|
+
* When the laptop's Wi-Fi IP changes, the URL stored from the last QR scan
|
|
17
|
+
* goes stale. We then retry alternate hosts (Metro / EXPO_PUBLIC_LOCAL_MINIAPP_HOST,
|
|
18
|
+
* plus an mDNS name captured at scan time) and persist the working URL so
|
|
19
|
+
* the next launch doesn't need a re-scan.
|
|
15
20
|
*/
|
|
16
21
|
export type DevManifest = {
|
|
17
22
|
packageName?: string;
|
|
@@ -25,20 +30,26 @@ export type DevManifest = {
|
|
|
25
30
|
export type DevLaunchResult = {
|
|
26
31
|
decision: "live";
|
|
27
32
|
manifest: DevManifest;
|
|
33
|
+
resolvedUrl: string;
|
|
28
34
|
} | {
|
|
29
35
|
decision: "offline";
|
|
30
36
|
manifest: null;
|
|
37
|
+
resolvedUrl?: undefined;
|
|
38
|
+
};
|
|
39
|
+
export type DecideDevLaunchOptions = {
|
|
40
|
+
/** Extra hostnames / IPs to try if `devUrl` is unreachable (no scheme/port). */
|
|
41
|
+
alternateHosts?: string[];
|
|
31
42
|
};
|
|
32
43
|
/**
|
|
33
|
-
* GET <devUrl>/miniapp.json with a hard timeout
|
|
44
|
+
* GET <devUrl>/miniapp.json with a hard timeout, retrying once on a
|
|
45
|
+
* network-layer failure (DNS/connection/abort) before trying alternate
|
|
46
|
+
* hosts (Metro laptop IP, mDNS name from the QR). Returns the parsed
|
|
34
47
|
* manifest on success ("live") or null ("offline").
|
|
35
48
|
*
|
|
36
|
-
* Side
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* The fetch doubles as the reachability probe AND the manifest source —
|
|
41
|
-
* one request per launch attempt instead of two.
|
|
49
|
+
* Side effects on success:
|
|
50
|
+
* - writes <packageName>_dev_last_reachable
|
|
51
|
+
* - if an alternate host worked, rewrites <packageName>_dev_url so the
|
|
52
|
+
* next launch skips the stale IP
|
|
42
53
|
*/
|
|
43
|
-
export declare function decideDevLaunchRoute(packageName: string, devUrl: string): Promise<DevLaunchResult>;
|
|
54
|
+
export declare function decideDevLaunchRoute(packageName: string, devUrl: string, options?: DecideDevLaunchOptions): Promise<DevLaunchResult>;
|
|
44
55
|
//# sourceMappingURL=devMiniappLaunch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devMiniappLaunch.d.ts","sourceRoot":"","sources":["../../src/utils/devMiniappLaunch.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"devMiniappLaunch.d.ts","sourceRoot":"","sources":["../../src/utils/devMiniappLaunch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAgBH,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,eAAe,GACvB;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,WAAW,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAC,GAC9D;IAAC,QAAQ,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,SAAS,CAAA;CAAC,CAAA;AAElE,MAAM,MAAM,sBAAsB,GAAG;IACnC,gFAAgF;IAChF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B,CAAA;AA4FD;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,eAAe,CAAC,CAoC1B"}
|
|
@@ -12,21 +12,28 @@
|
|
|
12
12
|
* get it in the same round trip — no second fetch.
|
|
13
13
|
*
|
|
14
14
|
* Pre-flighting at the call site keeps /applet/local a pure mount route.
|
|
15
|
+
*
|
|
16
|
+
* When the laptop's Wi-Fi IP changes, the URL stored from the last QR scan
|
|
17
|
+
* goes stale. We then retry alternate hosts (Metro / EXPO_PUBLIC_LOCAL_MINIAPP_HOST,
|
|
18
|
+
* plus an mDNS name captured at scan time) and persist the working URL so
|
|
19
|
+
* the next launch doesn't need a re-scan.
|
|
15
20
|
*/
|
|
21
|
+
import { configuredDevHost } from "./configuredDevHost";
|
|
16
22
|
import { storage } from "./storage/storage";
|
|
17
23
|
const REACHABILITY_TIMEOUT_MS = 1500;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
// A single dropped DNS lookup or momentary Wi-Fi blip (AP roam, DHCP renewal,
|
|
25
|
+
// phone hopping to cellular for a beat) looks identical to a dead dev server —
|
|
26
|
+
// both throw out of fetch(). Retrying once absorbs that transient case instead
|
|
27
|
+
// of bouncing straight to the offline screen. We do NOT retry a real HTTP
|
|
28
|
+
// response (res.ok === false): that's the server telling us something
|
|
29
|
+
// definitive, not a network-layer hiccup.
|
|
30
|
+
const REACHABILITY_MAX_ATTEMPTS = 2;
|
|
31
|
+
const REACHABILITY_RETRY_DELAY_MS = 400;
|
|
32
|
+
function delay(ms) {
|
|
33
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
34
|
+
}
|
|
35
|
+
/** Single GET <devUrl>/miniapp.json attempt with a hard timeout. */
|
|
36
|
+
async function fetchManifestOnce(devUrl) {
|
|
30
37
|
const controller = new AbortController();
|
|
31
38
|
const timer = setTimeout(() => controller.abort(), REACHABILITY_TIMEOUT_MS);
|
|
32
39
|
try {
|
|
@@ -35,18 +42,134 @@ export async function decideDevLaunchRoute(packageName, devUrl) {
|
|
|
35
42
|
signal: controller.signal,
|
|
36
43
|
});
|
|
37
44
|
if (!res.ok)
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
if (packageName) {
|
|
41
|
-
storage.save(`${packageName}_dev_last_reachable`, Date.now());
|
|
42
|
-
}
|
|
43
|
-
return { decision: "live", manifest };
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
return { decision: "offline", manifest: null };
|
|
45
|
+
return null;
|
|
46
|
+
return (await res.json());
|
|
47
47
|
}
|
|
48
48
|
finally {
|
|
49
49
|
clearTimeout(timer);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
function rewriteHost(devUrl, host) {
|
|
53
|
+
const trimmed = host.trim();
|
|
54
|
+
if (!trimmed)
|
|
55
|
+
return null;
|
|
56
|
+
try {
|
|
57
|
+
const url = new URL(devUrl);
|
|
58
|
+
if (url.hostname === trimmed)
|
|
59
|
+
return null;
|
|
60
|
+
url.hostname = trimmed;
|
|
61
|
+
return url.toString().replace(/\/$/, "");
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Point an http(s) icon at the host that actually answered. Cached dev icons are
|
|
69
|
+
* local `file://` paths and third-party icons live on unrelated hosts, so only
|
|
70
|
+
* icons still served by the stale dev host are rewritten.
|
|
71
|
+
*/
|
|
72
|
+
function rewriteIconHost(iconUrl, staleDevUrl, resolvedDevUrl) {
|
|
73
|
+
try {
|
|
74
|
+
const icon = new URL(iconUrl);
|
|
75
|
+
if (icon.protocol !== "http:" && icon.protocol !== "https:")
|
|
76
|
+
return null;
|
|
77
|
+
const stale = new URL(staleDevUrl);
|
|
78
|
+
const resolved = new URL(resolvedDevUrl);
|
|
79
|
+
// Compare host (hostname+port) so an icon on the same hostname but a
|
|
80
|
+
// different service port is left alone.
|
|
81
|
+
if (icon.host !== stale.host)
|
|
82
|
+
return null;
|
|
83
|
+
icon.host = resolved.host;
|
|
84
|
+
return icon.toString();
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function collectAlternateHosts(packageName, extra) {
|
|
91
|
+
const hosts = [];
|
|
92
|
+
const push = (h) => {
|
|
93
|
+
const v = h?.trim();
|
|
94
|
+
if (v && !hosts.includes(v))
|
|
95
|
+
hosts.push(v);
|
|
96
|
+
};
|
|
97
|
+
push(configuredDevHost());
|
|
98
|
+
if (packageName) {
|
|
99
|
+
const mdns = storage.load(`${packageName}_dev_mdns`);
|
|
100
|
+
if (mdns.is_ok())
|
|
101
|
+
push(mdns.value);
|
|
102
|
+
}
|
|
103
|
+
for (const h of extra ?? [])
|
|
104
|
+
push(h);
|
|
105
|
+
return hosts;
|
|
106
|
+
}
|
|
107
|
+
async function probeUrl(devUrl) {
|
|
108
|
+
for (let attempt = 1; attempt <= REACHABILITY_MAX_ATTEMPTS; attempt++) {
|
|
109
|
+
try {
|
|
110
|
+
const manifest = await fetchManifestOnce(devUrl);
|
|
111
|
+
// Definitive HTTP failure — do not retry this URL further.
|
|
112
|
+
if (!manifest)
|
|
113
|
+
return null;
|
|
114
|
+
return manifest;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
if (attempt < REACHABILITY_MAX_ATTEMPTS) {
|
|
118
|
+
await delay(REACHABILITY_RETRY_DELAY_MS);
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
return "network-error";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return "network-error";
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* GET <devUrl>/miniapp.json with a hard timeout, retrying once on a
|
|
128
|
+
* network-layer failure (DNS/connection/abort) before trying alternate
|
|
129
|
+
* hosts (Metro laptop IP, mDNS name from the QR). Returns the parsed
|
|
130
|
+
* manifest on success ("live") or null ("offline").
|
|
131
|
+
*
|
|
132
|
+
* Side effects on success:
|
|
133
|
+
* - writes <packageName>_dev_last_reachable
|
|
134
|
+
* - if an alternate host worked, rewrites <packageName>_dev_url so the
|
|
135
|
+
* next launch skips the stale IP
|
|
136
|
+
*/
|
|
137
|
+
export async function decideDevLaunchRoute(packageName, devUrl, options) {
|
|
138
|
+
const candidates = [devUrl];
|
|
139
|
+
for (const host of collectAlternateHosts(packageName, options?.alternateHosts)) {
|
|
140
|
+
const rewritten = rewriteHost(devUrl, host);
|
|
141
|
+
if (rewritten && !candidates.includes(rewritten))
|
|
142
|
+
candidates.push(rewritten);
|
|
143
|
+
}
|
|
144
|
+
for (const candidate of candidates) {
|
|
145
|
+
const result = await probeUrl(candidate);
|
|
146
|
+
if (result === "network-error" || result === null)
|
|
147
|
+
continue;
|
|
148
|
+
if (packageName) {
|
|
149
|
+
storage.save(`${packageName}_dev_last_reachable`, Date.now());
|
|
150
|
+
if (candidate !== devUrl) {
|
|
151
|
+
storage.save(`${packageName}_dev_url`, candidate);
|
|
152
|
+
// Keep _dev_meta.devUrl in sync when present so home-tile reads match.
|
|
153
|
+
const metaRes = storage.load(`${packageName}_dev_meta`);
|
|
154
|
+
if (metaRes.is_ok()) {
|
|
155
|
+
try {
|
|
156
|
+
const meta = JSON.parse(metaRes.value);
|
|
157
|
+
meta.devUrl = candidate;
|
|
158
|
+
if (typeof meta.iconUrl === "string") {
|
|
159
|
+
const rewritten = rewriteIconHost(meta.iconUrl, devUrl, candidate);
|
|
160
|
+
if (rewritten)
|
|
161
|
+
meta.iconUrl = rewritten;
|
|
162
|
+
}
|
|
163
|
+
storage.save(`${packageName}_dev_meta`, JSON.stringify(meta));
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
/* ignore malformed meta */
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return { decision: "live", manifest: result, resolvedUrl: candidate };
|
|
172
|
+
}
|
|
173
|
+
return { decision: "offline", manifest: null };
|
|
174
|
+
}
|
|
52
175
|
//# sourceMappingURL=devMiniappLaunch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devMiniappLaunch.js","sourceRoot":"","sources":["../../src/utils/devMiniappLaunch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AAEzC,MAAM,uBAAuB,GAAG,IAAI,CAAA;AAgBpC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,WAAmB,EACnB,MAAc;IAEd,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;IACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,uBAAuB,CAAC,CAAA;IAC3E,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,EAAE;YACnE,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAA;QACzD,MAAM,QAAQ,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgB,CAAA;QAClD,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,qBAAqB,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;QAC/D,CAAC;QACD,OAAO,EAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAC,CAAA;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAA;IAC9C,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAA;IACrB,CAAC;AACH,CAAC","sourcesContent":["/**\n * decideDevLaunchRoute — pre-flight reachability + manifest fetch for dev\n * miniapp launches.\n *\n * Every entry point that wants to launch a dev miniapp (home tile, QR\n * scan, URL screen, dev-offline \"Try again\" button) calls this BEFORE\n * navigating, so:\n *\n * 1. We land on the right destination in a single transition\n * (live mount vs offline takeover) — no flash through /applet/local.\n * 2. Callers that need the manifest (permission gate, name/icon read)\n * get it in the same round trip — no second fetch.\n *\n * Pre-flighting at the call site keeps /applet/local a pure mount route.\n */\n\nimport {storage} from \"./storage/storage\"\n\nconst REACHABILITY_TIMEOUT_MS = 1500\n\nexport type DevManifest = {\n packageName?: string\n name?: string\n /** First-found of `icon` / `iconUrl` / `logoUrl` (relative or absolute). */\n icon?: string\n permissions?: unknown\n hardwareRequirements?: unknown\n [key: string]: unknown\n}\n\nexport type DevLaunchResult =\n | {decision: \"live\"; manifest: DevManifest}\n | {decision: \"offline\"; manifest: null}\n\n/**\n * GET <devUrl>/miniapp.json with a hard timeout. Returns the parsed\n * manifest on success (\"live\") or null (\"offline\").\n *\n * Side effect: on success, writes <packageName>_dev_last_reachable so\n * the dev-offline screen can show \"Last reached: N min ago\" the next\n * time the user lands there.\n *\n * The fetch doubles as the reachability probe AND the manifest source —\n * one request per launch attempt instead of two.\n */\nexport async function decideDevLaunchRoute(\n packageName: string,\n devUrl: string,\n): Promise<DevLaunchResult> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), REACHABILITY_TIMEOUT_MS)\n try {\n const res = await fetch(`${devUrl.replace(/\\/$/, \"\")}/miniapp.json`, {\n method: \"GET\",\n signal: controller.signal,\n })\n if (!res.ok) return {decision: \"offline\", manifest: null}\n const manifest = (await res.json()) as DevManifest\n if (packageName) {\n storage.save(`${packageName}_dev_last_reachable`, Date.now())\n }\n return {decision: \"live\", manifest}\n } catch {\n return {decision: \"offline\", manifest: null}\n } finally {\n clearTimeout(timer)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"devMiniappLaunch.js","sourceRoot":"","sources":["../../src/utils/devMiniappLaunch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * decideDevLaunchRoute — pre-flight reachability + manifest fetch for dev\n * miniapp launches.\n *\n * Every entry point that wants to launch a dev miniapp (home tile, QR\n * scan, URL screen, dev-offline \"Try again\" button) calls this BEFORE\n * navigating, so:\n *\n * 1. We land on the right destination in a single transition\n * (live mount vs offline takeover) — no flash through /applet/local.\n * 2. Callers that need the manifest (permission gate, name/icon read)\n * get it in the same round trip — no second fetch.\n *\n * Pre-flighting at the call site keeps /applet/local a pure mount route.\n *\n * When the laptop's Wi-Fi IP changes, the URL stored from the last QR scan\n * goes stale. We then retry alternate hosts (Metro / EXPO_PUBLIC_LOCAL_MINIAPP_HOST,\n * plus an mDNS name captured at scan time) and persist the working URL so\n * the next launch doesn't need a re-scan.\n */\n\nimport {configuredDevHost} from \"./configuredDevHost\"\nimport {storage} from \"./storage/storage\"\n\nconst REACHABILITY_TIMEOUT_MS = 1500\n\n// A single dropped DNS lookup or momentary Wi-Fi blip (AP roam, DHCP renewal,\n// phone hopping to cellular for a beat) looks identical to a dead dev server —\n// both throw out of fetch(). Retrying once absorbs that transient case instead\n// of bouncing straight to the offline screen. We do NOT retry a real HTTP\n// response (res.ok === false): that's the server telling us something\n// definitive, not a network-layer hiccup.\nconst REACHABILITY_MAX_ATTEMPTS = 2\nconst REACHABILITY_RETRY_DELAY_MS = 400\n\nexport type DevManifest = {\n packageName?: string\n name?: string\n /** First-found of `icon` / `iconUrl` / `logoUrl` (relative or absolute). */\n icon?: string\n permissions?: unknown\n hardwareRequirements?: unknown\n [key: string]: unknown\n}\n\nexport type DevLaunchResult =\n | {decision: \"live\"; manifest: DevManifest; resolvedUrl: string}\n | {decision: \"offline\"; manifest: null; resolvedUrl?: undefined}\n\nexport type DecideDevLaunchOptions = {\n /** Extra hostnames / IPs to try if `devUrl` is unreachable (no scheme/port). */\n alternateHosts?: string[]\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/** Single GET <devUrl>/miniapp.json attempt with a hard timeout. */\nasync function fetchManifestOnce(devUrl: string): Promise<DevManifest | null> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), REACHABILITY_TIMEOUT_MS)\n try {\n const res = await fetch(`${devUrl.replace(/\\/$/, \"\")}/miniapp.json`, {\n method: \"GET\",\n signal: controller.signal,\n })\n if (!res.ok) return null\n return (await res.json()) as DevManifest\n } finally {\n clearTimeout(timer)\n }\n}\n\nfunction rewriteHost(devUrl: string, host: string): string | null {\n const trimmed = host.trim()\n if (!trimmed) return null\n try {\n const url = new URL(devUrl)\n if (url.hostname === trimmed) return null\n url.hostname = trimmed\n return url.toString().replace(/\\/$/, \"\")\n } catch {\n return null\n }\n}\n\n/**\n * Point an http(s) icon at the host that actually answered. Cached dev icons are\n * local `file://` paths and third-party icons live on unrelated hosts, so only\n * icons still served by the stale dev host are rewritten.\n */\nfunction rewriteIconHost(iconUrl: string, staleDevUrl: string, resolvedDevUrl: string): string | null {\n try {\n const icon = new URL(iconUrl)\n if (icon.protocol !== \"http:\" && icon.protocol !== \"https:\") return null\n const stale = new URL(staleDevUrl)\n const resolved = new URL(resolvedDevUrl)\n // Compare host (hostname+port) so an icon on the same hostname but a\n // different service port is left alone.\n if (icon.host !== stale.host) return null\n icon.host = resolved.host\n return icon.toString()\n } catch {\n return null\n }\n}\n\nfunction collectAlternateHosts(packageName: string, extra?: string[]): string[] {\n const hosts: string[] = []\n const push = (h: string | undefined | null) => {\n const v = h?.trim()\n if (v && !hosts.includes(v)) hosts.push(v)\n }\n\n push(configuredDevHost())\n\n if (packageName) {\n const mdns = storage.load<string>(`${packageName}_dev_mdns`)\n if (mdns.is_ok()) push(mdns.value)\n }\n\n for (const h of extra ?? []) push(h)\n return hosts\n}\n\nasync function probeUrl(devUrl: string): Promise<DevManifest | null | \"network-error\"> {\n for (let attempt = 1; attempt <= REACHABILITY_MAX_ATTEMPTS; attempt++) {\n try {\n const manifest = await fetchManifestOnce(devUrl)\n // Definitive HTTP failure — do not retry this URL further.\n if (!manifest) return null\n return manifest\n } catch {\n if (attempt < REACHABILITY_MAX_ATTEMPTS) {\n await delay(REACHABILITY_RETRY_DELAY_MS)\n continue\n }\n return \"network-error\"\n }\n }\n return \"network-error\"\n}\n\n/**\n * GET <devUrl>/miniapp.json with a hard timeout, retrying once on a\n * network-layer failure (DNS/connection/abort) before trying alternate\n * hosts (Metro laptop IP, mDNS name from the QR). Returns the parsed\n * manifest on success (\"live\") or null (\"offline\").\n *\n * Side effects on success:\n * - writes <packageName>_dev_last_reachable\n * - if an alternate host worked, rewrites <packageName>_dev_url so the\n * next launch skips the stale IP\n */\nexport async function decideDevLaunchRoute(\n packageName: string,\n devUrl: string,\n options?: DecideDevLaunchOptions,\n): Promise<DevLaunchResult> {\n const candidates: string[] = [devUrl]\n for (const host of collectAlternateHosts(packageName, options?.alternateHosts)) {\n const rewritten = rewriteHost(devUrl, host)\n if (rewritten && !candidates.includes(rewritten)) candidates.push(rewritten)\n }\n\n for (const candidate of candidates) {\n const result = await probeUrl(candidate)\n if (result === \"network-error\" || result === null) continue\n\n if (packageName) {\n storage.save(`${packageName}_dev_last_reachable`, Date.now())\n if (candidate !== devUrl) {\n storage.save(`${packageName}_dev_url`, candidate)\n // Keep _dev_meta.devUrl in sync when present so home-tile reads match.\n const metaRes = storage.load<string>(`${packageName}_dev_meta`)\n if (metaRes.is_ok()) {\n try {\n const meta = JSON.parse(metaRes.value) as {devUrl?: string; iconUrl?: string}\n meta.devUrl = candidate\n if (typeof meta.iconUrl === \"string\") {\n const rewritten = rewriteIconHost(meta.iconUrl, devUrl, candidate)\n if (rewritten) meta.iconUrl = rewritten\n }\n storage.save(`${packageName}_dev_meta`, JSON.stringify(meta))\n } catch {\n /* ignore malformed meta */\n }\n }\n }\n }\n return {decision: \"live\", manifest: result, resolvedUrl: candidate}\n }\n\n return {decision: \"offline\", manifest: null}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnosticContext.d.ts","sourceRoot":"","sources":["../../src/utils/diagnosticContext.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"diagnosticContext.d.ts","sourceRoot":"","sources":["../../src/utils/diagnosticContext.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,sBAAsB,CAAA;AA4BvD,wBAAsB,wBAAwB,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CA0HrG"}
|
|
@@ -2,11 +2,14 @@ import NetInfo from "@react-native-community/netinfo";
|
|
|
2
2
|
import Constants from "expo-constants";
|
|
3
3
|
import * as Location from "expo-location";
|
|
4
4
|
import { Platform } from "react-native";
|
|
5
|
-
import
|
|
5
|
+
import appRegistry from "../services/AppRegistry";
|
|
6
|
+
import localMiniappRuntime from "../services/LocalMiniappRuntime";
|
|
7
|
+
import { getLastOpenTime, useAppStatusStore } from "../stores/apps";
|
|
6
8
|
import { useConnectionStore } from "../stores/connection";
|
|
7
9
|
import { useCoreStore } from "../stores/core";
|
|
8
10
|
import { useGlassesStore } from "../stores/glasses";
|
|
9
11
|
import { SETTINGS, useSettingsStore } from "../stores/settings";
|
|
12
|
+
import { buildMiniappDiagnosticContext } from "./miniappDiagnostics";
|
|
10
13
|
const SENSITIVE_SETTINGS_KEYS = ["core_token", "auth_token", "auth_email"];
|
|
11
14
|
const SENSITIVE_GLASSES_KEYS = ["hotspotPassword"];
|
|
12
15
|
/**
|
|
@@ -72,17 +75,15 @@ export async function collectDiagnosticContext(extra) {
|
|
|
72
75
|
}
|
|
73
76
|
const offlineMode = await useSettingsStore.getState().getSetting(SETTINGS.offline_mode.key);
|
|
74
77
|
const defaultWearable = await useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key);
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
local: app.local,
|
|
85
|
-
}));
|
|
78
|
+
const miniappRuntime = localMiniappRuntime.getDiagnosticSnapshot();
|
|
79
|
+
const miniapps = buildMiniappDiagnosticContext({
|
|
80
|
+
apps: appletState.apps,
|
|
81
|
+
foregroundedPackage: appletState.foregroundedPackage,
|
|
82
|
+
runtime: miniappRuntime,
|
|
83
|
+
getLastOpenedAtMs: (app) => getLastOpenTime(app.packageName),
|
|
84
|
+
getManifest: (app) => app.local && app.version ? appRegistry.getMiniappManifest(app.packageName, app.version) : undefined,
|
|
85
|
+
getReleaseIdentity: (app) => app.local && app.version ? appRegistry.getReleaseIdentity(app.packageName, app.version) : undefined,
|
|
86
|
+
});
|
|
86
87
|
return {
|
|
87
88
|
app: {
|
|
88
89
|
appVersion: process.env.EXPO_PUBLIC_MENTRAOS_VERSION || "version",
|
|
@@ -102,12 +103,9 @@ export async function collectDiagnosticContext(extra) {
|
|
|
102
103
|
runtime: {
|
|
103
104
|
core: coreState,
|
|
104
105
|
connection: connectionState,
|
|
106
|
+
miniapps: miniappRuntime,
|
|
105
107
|
},
|
|
106
|
-
apps:
|
|
107
|
-
apps,
|
|
108
|
-
installed: apps.map((app) => app.packageName),
|
|
109
|
-
running: apps.filter((app) => app.running).map((app) => app.packageName),
|
|
110
|
-
},
|
|
108
|
+
apps: miniapps,
|
|
111
109
|
settings: {
|
|
112
110
|
...filteredSettings,
|
|
113
111
|
offlineMode: !!offlineMode,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnosticContext.js","sourceRoot":"","sources":["../../src/utils/diagnosticContext.ts"],"names":[],"mappings":"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","sourcesContent":["import NetInfo from \"@react-native-community/netinfo\"\nimport Constants from \"expo-constants\"\nimport * as Location from \"expo-location\"\nimport {Platform} from \"react-native\"\nimport type {ReportContext} from \"@mentra/cloud-client\"\n\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {useConnectionStore} from \"../stores/connection\"\nimport {useCoreStore} from \"../stores/core\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\n\nconst SENSITIVE_SETTINGS_KEYS = [\"core_token\", \"auth_token\", \"auth_email\"] as const\nconst SENSITIVE_GLASSES_KEYS = [\"hotspotPassword\"] as const\n\n/**\n * The glasses store keeps hotspot credentials NESTED (`hotspot: {state, ssid,\n * password, localIp}`), not just on the legacy top-level `hotspotPassword` key —\n * strip the password before the state is attached to a report.\n */\nfunction redactNestedCredentials(glasses: Record<string, unknown>): Record<string, unknown> {\n const hotspot = glasses.hotspot\n if (hotspot && typeof hotspot === \"object\" && \"password\" in hotspot) {\n const {password: _password, ...rest} = hotspot as Record<string, unknown>\n return {...glasses, hotspot: {...rest, password: \"[REDACTED]\"}}\n }\n return glasses\n}\n\nexport async function collectDiagnosticContext(extra?: Partial<ReportContext>): Promise<ReportContext> {\n const appletState = useAppStatusStore.getState()\n const settingsState = useSettingsStore.getState()\n const {setCoreInfo: _setCoreInfo, reset: _resetBluetooth, ...coreState} = useCoreStore.getState()\n const {\n setStatus: _setConnectionStatus,\n setUrl: _setConnectionUrl,\n setError: _setConnectionError,\n incrementReconnectAttempts: _incrementReconnectAttempts,\n resetReconnectAttempts: _resetReconnectAttempts,\n reset: _resetConnection,\n ...connectionState\n } = useConnectionStore.getState()\n const {\n setGlassesInfo: _setGlassesInfo,\n setBatteryInfo: _setBatteryInfo,\n setWifiInfo: _setWifiInfo,\n setHotspotInfo: _setHotspotInfo,\n setOtaUpdateAvailable: _setOtaUpdateAvailable,\n setOtaProgress: _setOtaProgress,\n setOtaInProgress: _setOtaInProgress,\n setMtkUpdatedThisSession: _setMtkUpdatedThisSession,\n clearOtaState: _clearOtaState,\n reset: _resetGlasses,\n ...glassesState\n } = useGlassesStore.getState()\n\n const filteredGlasses = redactNestedCredentials(\n Object.fromEntries(\n Object.entries(glassesState).filter(\n ([key]) => !SENSITIVE_GLASSES_KEYS.includes(key as (typeof SENSITIVE_GLASSES_KEYS)[number]),\n ),\n ),\n )\n const filteredSettings = Object.fromEntries(\n Object.entries(settingsState.settings || {}).filter(\n ([key]) => !SENSITIVE_SETTINGS_KEYS.includes(key as (typeof SENSITIVE_SETTINGS_KEYS)[number]),\n ),\n )\n\n let networkInfo: Record<string, unknown> = {type: \"unknown\", isConnected: false, isInternetReachable: false}\n try {\n const netState = await NetInfo.fetch()\n networkInfo = {\n type: netState.type,\n isConnected: netState.isConnected ?? false,\n isInternetReachable: netState.isInternetReachable ?? false,\n }\n } catch (error) {\n console.log(\"diagnosticContext: failed to get network info:\", error)\n }\n\n let locationInfo: Record<string, unknown> | undefined\n try {\n const {status} = await Location.getForegroundPermissionsAsync()\n if (status === \"granted\") {\n const location = await Location.getLastKnownPositionAsync()\n if (location) {\n locationInfo = {\n latitude: Number(location.coords.latitude.toFixed(4)),\n longitude: Number(location.coords.longitude.toFixed(4)),\n }\n try {\n const [place] = await Location.reverseGeocodeAsync({\n latitude: location.coords.latitude,\n longitude: location.coords.longitude,\n })\n if (place) {\n locationInfo.place = [place.city, place.region, place.country].filter(Boolean).join(\", \")\n }\n } catch (error) {\n console.log(\"diagnosticContext: failed to reverse geocode:\", error)\n }\n }\n }\n } catch (error) {\n console.log(\"diagnosticContext: failed to get location:\", error)\n }\n\n const offlineMode = await useSettingsStore.getState().getSetting(SETTINGS.offline_mode.key)\n const defaultWearable = await useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key)\n const apps = appletState.apps.map((app) => ({\n packageName: app.packageName,\n name: app.name,\n running: app.running,\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 }))\n\n return {\n app: {\n appVersion: process.env.EXPO_PUBLIC_MENTRAOS_VERSION || \"version\",\n buildCommit: process.env.EXPO_PUBLIC_BUILD_COMMIT || \"commit\",\n buildBranch: process.env.EXPO_PUBLIC_BUILD_BRANCH || \"branch\",\n buildTime: process.env.EXPO_PUBLIC_BUILD_TIME || \"time\",\n buildUser: process.env.EXPO_PUBLIC_BUILD_USER || \"user\",\n },\n phone: {\n deviceName: Constants.deviceName || \"deviceName\",\n osVersion: `${Platform.OS} ${Platform.Version}`,\n platform: Platform.OS,\n network: networkInfo,\n location: locationInfo,\n },\n glasses: filteredGlasses,\n runtime: {\n core: coreState,\n connection: connectionState,\n },\n apps: {\n apps,\n installed: apps.map((app) => app.packageName),\n running: apps.filter((app) => app.running).map((app) => app.packageName),\n },\n settings: {\n ...filteredSettings,\n offlineMode: !!offlineMode,\n defaultWearable,\n },\n ...extra,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"diagnosticContext.js","sourceRoot":"","sources":["../../src/utils/diagnosticContext.ts"],"names":[],"mappings":"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","sourcesContent":["import NetInfo from \"@react-native-community/netinfo\"\nimport Constants from \"expo-constants\"\nimport * as Location from \"expo-location\"\nimport {Platform} from \"react-native\"\nimport type {ReportContext} from \"@mentra/cloud-client\"\n\nimport appRegistry from \"../services/AppRegistry\"\nimport localMiniappRuntime from \"../services/LocalMiniappRuntime\"\nimport {getLastOpenTime, useAppStatusStore} from \"../stores/apps\"\nimport {useConnectionStore} from \"../stores/connection\"\nimport {useCoreStore} from \"../stores/core\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {buildMiniappDiagnosticContext} from \"./miniappDiagnostics\"\n\nconst SENSITIVE_SETTINGS_KEYS = [\"core_token\", \"auth_token\", \"auth_email\"] as const\nconst SENSITIVE_GLASSES_KEYS = [\"hotspotPassword\"] as const\n\n/**\n * The glasses store keeps hotspot credentials NESTED (`hotspot: {state, ssid,\n * password, localIp}`), not just on the legacy top-level `hotspotPassword` key —\n * strip the password before the state is attached to a report.\n */\nfunction redactNestedCredentials(glasses: Record<string, unknown>): Record<string, unknown> {\n const hotspot = glasses.hotspot\n if (hotspot && typeof hotspot === \"object\" && \"password\" in hotspot) {\n const {password: _password, ...rest} = hotspot as Record<string, unknown>\n return {...glasses, hotspot: {...rest, password: \"[REDACTED]\"}}\n }\n return glasses\n}\n\nexport async function collectDiagnosticContext(extra?: Partial<ReportContext>): Promise<ReportContext> {\n const appletState = useAppStatusStore.getState()\n const settingsState = useSettingsStore.getState()\n const {setCoreInfo: _setCoreInfo, reset: _resetBluetooth, ...coreState} = useCoreStore.getState()\n const {\n setStatus: _setConnectionStatus,\n setUrl: _setConnectionUrl,\n setError: _setConnectionError,\n incrementReconnectAttempts: _incrementReconnectAttempts,\n resetReconnectAttempts: _resetReconnectAttempts,\n reset: _resetConnection,\n ...connectionState\n } = useConnectionStore.getState()\n const {\n setGlassesInfo: _setGlassesInfo,\n setBatteryInfo: _setBatteryInfo,\n setWifiInfo: _setWifiInfo,\n setHotspotInfo: _setHotspotInfo,\n setOtaUpdateAvailable: _setOtaUpdateAvailable,\n setOtaProgress: _setOtaProgress,\n setOtaInProgress: _setOtaInProgress,\n setMtkUpdatedThisSession: _setMtkUpdatedThisSession,\n clearOtaState: _clearOtaState,\n reset: _resetGlasses,\n ...glassesState\n } = useGlassesStore.getState()\n\n const filteredGlasses = redactNestedCredentials(\n Object.fromEntries(\n Object.entries(glassesState).filter(\n ([key]) => !SENSITIVE_GLASSES_KEYS.includes(key as (typeof SENSITIVE_GLASSES_KEYS)[number]),\n ),\n ),\n )\n const filteredSettings = Object.fromEntries(\n Object.entries(settingsState.settings || {}).filter(\n ([key]) => !SENSITIVE_SETTINGS_KEYS.includes(key as (typeof SENSITIVE_SETTINGS_KEYS)[number]),\n ),\n )\n\n let networkInfo: Record<string, unknown> = {type: \"unknown\", isConnected: false, isInternetReachable: false}\n try {\n const netState = await NetInfo.fetch()\n networkInfo = {\n type: netState.type,\n isConnected: netState.isConnected ?? false,\n isInternetReachable: netState.isInternetReachable ?? false,\n }\n } catch (error) {\n console.log(\"diagnosticContext: failed to get network info:\", error)\n }\n\n let locationInfo: Record<string, unknown> | undefined\n try {\n const {status} = await Location.getForegroundPermissionsAsync()\n if (status === \"granted\") {\n const location = await Location.getLastKnownPositionAsync()\n if (location) {\n locationInfo = {\n latitude: Number(location.coords.latitude.toFixed(4)),\n longitude: Number(location.coords.longitude.toFixed(4)),\n }\n try {\n const [place] = await Location.reverseGeocodeAsync({\n latitude: location.coords.latitude,\n longitude: location.coords.longitude,\n })\n if (place) {\n locationInfo.place = [place.city, place.region, place.country].filter(Boolean).join(\", \")\n }\n } catch (error) {\n console.log(\"diagnosticContext: failed to reverse geocode:\", error)\n }\n }\n }\n } catch (error) {\n console.log(\"diagnosticContext: failed to get location:\", error)\n }\n\n const offlineMode = await useSettingsStore.getState().getSetting(SETTINGS.offline_mode.key)\n const defaultWearable = await useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key)\n const miniappRuntime = localMiniappRuntime.getDiagnosticSnapshot()\n const miniapps = buildMiniappDiagnosticContext({\n apps: appletState.apps,\n foregroundedPackage: appletState.foregroundedPackage,\n runtime: miniappRuntime,\n getLastOpenedAtMs: (app) => getLastOpenTime(app.packageName),\n getManifest: (app) =>\n app.local && app.version ? appRegistry.getMiniappManifest(app.packageName, app.version) : undefined,\n getReleaseIdentity: (app) =>\n app.local && app.version ? appRegistry.getReleaseIdentity(app.packageName, app.version) : undefined,\n })\n\n return {\n app: {\n appVersion: process.env.EXPO_PUBLIC_MENTRAOS_VERSION || \"version\",\n buildCommit: process.env.EXPO_PUBLIC_BUILD_COMMIT || \"commit\",\n buildBranch: process.env.EXPO_PUBLIC_BUILD_BRANCH || \"branch\",\n buildTime: process.env.EXPO_PUBLIC_BUILD_TIME || \"time\",\n buildUser: process.env.EXPO_PUBLIC_BUILD_USER || \"user\",\n },\n phone: {\n deviceName: Constants.deviceName || \"deviceName\",\n osVersion: `${Platform.OS} ${Platform.Version}`,\n platform: Platform.OS,\n network: networkInfo,\n location: locationInfo,\n },\n glasses: filteredGlasses,\n runtime: {\n core: coreState,\n connection: connectionState,\n miniapps: miniappRuntime,\n },\n apps: miniapps,\n settings: {\n ...filteredSettings,\n offlineMode: !!offlineMode,\n defaultWearable,\n },\n ...extra,\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hardware.d.ts","sourceRoot":"","sources":["../../../src/utils/hardware/hardware.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"hardware.d.ts","sourceRoot":"","sources":["../../../src/utils/hardware/hardware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAe,mBAAmB,EAA2D,MAAM,aAAa,CAAA;AAEpI;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,OAAO,CAAA;IACrB,eAAe,EAAE,mBAAmB,EAAE,CAAA;IACtC,eAAe,EAAE,mBAAmB,EAAE,CAAA;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;GAEG;AACH,qBAAa,qBAAqB;IAChC;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CACvB,oBAAoB,EAAE,mBAAmB,EAAE,EAC3C,YAAY,EAAE,YAAY,GAAG,IAAI,GAChC,mBAAmB;IAkCtB;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,sBAAsB;IA4CrC;;;;OAIG;IACH,MAAM,CAAC,uBAAuB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM;IAkBnE;;;;OAIG;IACH,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE;CA0BlE"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { simulatedGlasses } from "../../types";
|
|
1
|
+
import { DeviceTypes, HardwareRequirementLevel, HardwareType, simulatedGlasses } from "../../types";
|
|
3
2
|
/**
|
|
4
3
|
* Service for checking hardware compatibility between apps and glasses
|
|
5
4
|
*/
|
|
@@ -59,7 +58,12 @@ export class HardwareCompatibility {
|
|
|
59
58
|
case HardwareType.DISPLAY:
|
|
60
59
|
return capabilities.hasDisplay;
|
|
61
60
|
case HardwareType.MICROPHONE:
|
|
62
|
-
|
|
61
|
+
// MentraOS always provides an audio-input path. When the connected
|
|
62
|
+
// glasses do not have an onboard microphone, the engine falls back to
|
|
63
|
+
// the phone microphone. Keep `capabilities.hasMicrophone` reserved for
|
|
64
|
+
// physical-device/source selection; app compatibility is about whether
|
|
65
|
+
// the requested input is available to the miniapp.
|
|
66
|
+
return true;
|
|
63
67
|
case HardwareType.SPEAKER:
|
|
64
68
|
return capabilities.hasSpeaker;
|
|
65
69
|
case HardwareType.IMU:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../../src/utils/hardware/hardware.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../../src/utils/hardware/hardware.ts"],"names":[],"mappings":"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","sourcesContent":["import {Capabilities, DeviceTypes, HardwareRequirement, HardwareRequirementLevel, HardwareType, simulatedGlasses} from \"../../types\"\n\n/**\n * Result of a hardware compatibility check\n */\nexport interface CompatibilityResult {\n isCompatible: boolean\n missingRequired: HardwareRequirement[]\n missingOptional: HardwareRequirement[]\n warnings: string[]\n}\n\n/**\n * Service for checking hardware compatibility between apps and glasses\n */\nexport class HardwareCompatibility {\n /**\n * Check if app is compatible with given device capabilities\n * @param app The app to check\n * @param capabilities The device capabilities (null if no device connected)\n * @returns Detailed compatibility result\n */\n static checkCompatibility(\n hardwareRequirements: HardwareRequirement[],\n capabilities: Capabilities | null,\n ): CompatibilityResult {\n const result: CompatibilityResult = {\n isCompatible: true,\n missingRequired: [],\n missingOptional: [],\n warnings: [],\n }\n\n // If no hardware requirements specified, app is compatible with any hardware\n if (hardwareRequirements.length === 0) {\n return result\n }\n\n // If no capabilities available assume simulated glasses:\n if (!capabilities) {\n capabilities = simulatedGlasses\n }\n\n // Check each hardware requirement\n for (const requirement of hardwareRequirements) {\n const hasHardware = this.checkHardwareAvailable(requirement.type, capabilities!)\n if (!hasHardware) {\n if (requirement.level === HardwareRequirementLevel.REQUIRED) {\n result.missingRequired.push(requirement)\n result.isCompatible = false\n } else {\n result.missingOptional.push(requirement)\n }\n }\n }\n\n return result\n }\n\n /**\n * Check if specific hardware is available in capabilities\n * @param hardwareType The type of hardware to check\n * @param capabilities The device capabilities\n * @returns true if hardware is available\n */\n private static checkHardwareAvailable(hardwareType: HardwareType, capabilities: Capabilities): boolean {\n if (hardwareType === HardwareType.EXIST) {\n if (capabilities.modelName === DeviceTypes.NONE) {\n return false\n }\n return true\n }\n\n switch (hardwareType) {\n case HardwareType.CAMERA:\n return capabilities.hasCamera\n\n case HardwareType.DISPLAY:\n return capabilities.hasDisplay\n\n case HardwareType.MICROPHONE:\n // MentraOS always provides an audio-input path. When the connected\n // glasses do not have an onboard microphone, the engine falls back to\n // the phone microphone. Keep `capabilities.hasMicrophone` reserved for\n // physical-device/source selection; app compatibility is about whether\n // the requested input is available to the miniapp.\n return true\n\n case HardwareType.SPEAKER:\n return capabilities.hasSpeaker\n\n case HardwareType.IMU:\n return capabilities.hasIMU\n\n case HardwareType.BUTTON:\n return capabilities.hasButton\n\n case HardwareType.LIGHT:\n return capabilities.hasLight\n\n case HardwareType.WIFI:\n return capabilities.hasWifi\n\n default:\n // Unknown hardware type - assume not available\n return false\n }\n }\n\n /**\n * Get human-readable compatibility message\n * @param result The compatibility check result\n * @returns User-friendly message about compatibility\n */\n static getCompatibilityMessage(result: CompatibilityResult): string {\n if (result.isCompatible) {\n if (result.missingOptional.length > 0) {\n const optionalHardware = result.missingOptional.map((req) => req.type.toLowerCase()).join(\", \")\n return `This app works with your glasses but has optional features that require: ${optionalHardware}`\n }\n return \"This app is fully compatible with your glasses\"\n }\n\n const requiredHardware = result.missingRequired.map((req) => req.type.toLowerCase()).join(\", \")\n\n if (result.missingRequired.length === 1) {\n return `This app requires a ${requiredHardware} which is not available on your connected glasses`\n } else {\n return `This app requires the following hardware which is not available on your connected glasses: ${requiredHardware}`\n }\n }\n\n /**\n * Get detailed compatibility messages including descriptions\n * @param result The compatibility check result\n * @returns Array of detailed messages\n */\n static getDetailedMessages(result: CompatibilityResult): string[] {\n const messages: string[] = []\n\n // Add warnings first\n messages.push(...result.warnings)\n\n // Add missing required hardware\n for (const req of result.missingRequired) {\n let message = `❌ Missing required ${req.type.toLowerCase()}`\n if (req.description) {\n message += `: ${req.description}`\n }\n messages.push(message)\n }\n\n // Add missing optional hardware\n for (const req of result.missingOptional) {\n let message = `⚠️ Missing optional ${req.type.toLowerCase()}`\n if (req.description) {\n message += `: ${req.description}`\n }\n messages.push(message)\n }\n\n return messages\n }\n}\n"]}
|