@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.
- 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
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {useEffect, useRef, useState} from "react"
|
|
2
|
+
|
|
3
|
+
export function useEngineSnapshot<T>(getSnapshot: () => T, subscribe: (onChange: () => void) => () => void): T {
|
|
4
|
+
const getSnapshotRef = useRef(getSnapshot)
|
|
5
|
+
const subscribeRef = useRef(subscribe)
|
|
6
|
+
getSnapshotRef.current = getSnapshot
|
|
7
|
+
subscribeRef.current = subscribe
|
|
8
|
+
const [snapshot, setSnapshot] = useState(() => getSnapshot())
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
setSnapshot(getSnapshotRef.current())
|
|
12
|
+
return subscribeRef.current(() => setSnapshot(getSnapshotRef.current()))
|
|
13
|
+
}, [])
|
|
14
|
+
|
|
15
|
+
return snapshot
|
|
16
|
+
}
|
package/src/runtime/bootstrap.ts
CHANGED
|
@@ -50,9 +50,22 @@ export interface IslandUiSeams {
|
|
|
50
50
|
* `session.glasses.requestWifiSetup` — open the host's glasses Wi-Fi setup
|
|
51
51
|
* flow. Absent ⇒ miniapps get NOT_IMPLEMENTED for the request.
|
|
52
52
|
*/
|
|
53
|
-
requestWifiSetup?: (reason?: string) => Promise<void> | void
|
|
53
|
+
requestWifiSetup?: (reason?: string, packageName?: string) => Promise<void> | void
|
|
54
|
+
/**
|
|
55
|
+
* `session.system.scanQr` — open a phone-camera QR scanner overlay. Must NOT
|
|
56
|
+
* clear miniapp foreground: UI_CLOSE on a live call hangs it up. Absent ⇒
|
|
57
|
+
* miniapps get NOT_IMPLEMENTED.
|
|
58
|
+
*/
|
|
59
|
+
scanQr?: (options?: ScanQrOptions) => Promise<ScanQrResult>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ScanQrOptions {
|
|
63
|
+
title?: string
|
|
64
|
+
hint?: string
|
|
54
65
|
}
|
|
55
66
|
|
|
67
|
+
export type ScanQrResult = {data: string} | {cancelled: true}
|
|
68
|
+
|
|
56
69
|
export interface IslandConfigureOptions {
|
|
57
70
|
/** REQUIRED — the only must-have seam. The host owns login; engine owns the rest. */
|
|
58
71
|
auth: IslandAuth
|
|
@@ -81,6 +94,19 @@ export function configure(opts: IslandConfigureOptions): void {
|
|
|
81
94
|
options = opts
|
|
82
95
|
}
|
|
83
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Merge host-UI seams after configure/start. UI capabilities (scan overlay,
|
|
99
|
+
* wifi setup) are looked up per request, so this is safe on a running runtime.
|
|
100
|
+
* Used so Metro reloads can attach seams that missed the original configure().
|
|
101
|
+
*/
|
|
102
|
+
export function updateUiSeams(ui: IslandUiSeams): void {
|
|
103
|
+
if (!options) {
|
|
104
|
+
console.warn("engine.updateUiSeams() called before engine.configure(); ignored")
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
options = {...options, ui: {...options.ui, ...ui}}
|
|
108
|
+
}
|
|
109
|
+
|
|
84
110
|
/** Mark the runtime started. Idempotent. */
|
|
85
111
|
export async function start(): Promise<void> {
|
|
86
112
|
if (started) return
|
|
@@ -99,6 +125,12 @@ export function isStarted(): boolean {
|
|
|
99
125
|
return started
|
|
100
126
|
}
|
|
101
127
|
|
|
128
|
+
/** Test-only: wipe configure state so suites can start from a cold host. */
|
|
129
|
+
export function resetForTests(): void {
|
|
130
|
+
options = null
|
|
131
|
+
started = false
|
|
132
|
+
}
|
|
133
|
+
|
|
102
134
|
/** The host-supplied auth provider, or null if not configured yet. */
|
|
103
135
|
export function getAuth(): IslandAuth | null {
|
|
104
136
|
return options?.auth ?? null
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type {ScanQrOptions, ScanQrResult} from "./bootstrap"
|
|
2
|
+
|
|
3
|
+
export class ScanQrNotConfiguredError extends Error {
|
|
4
|
+
readonly code = "NOT_IMPLEMENTED"
|
|
5
|
+
constructor() {
|
|
6
|
+
super("QR scanning is not configured on this host. Reload the Mentra App and try again.")
|
|
7
|
+
this.name = "ScanQrNotConfiguredError"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export async function invokeScanQrSeam(
|
|
12
|
+
scanQr: ((options?: ScanQrOptions) => Promise<ScanQrResult>) | undefined,
|
|
13
|
+
payload: Record<string, unknown> = {},
|
|
14
|
+
): Promise<ScanQrResult> {
|
|
15
|
+
if (!scanQr) throw new ScanQrNotConfiguredError()
|
|
16
|
+
return scanQr({
|
|
17
|
+
title: typeof payload.title === "string" ? payload.title : undefined,
|
|
18
|
+
hint: typeof payload.hint === "string" ? payload.hint : undefined,
|
|
19
|
+
})
|
|
20
|
+
}
|
|
@@ -22,14 +22,17 @@ import {unzip} from "react-native-zip-archive"
|
|
|
22
22
|
import semver from "semver"
|
|
23
23
|
import {AsyncResult, Result, result as Res} from "typesafe-ts"
|
|
24
24
|
|
|
25
|
-
import type {AppletPermission, AppPermissionType, AppletType, ClientApp
|
|
25
|
+
import type {AppletPermission, AppPermissionType, AppletType, ClientApp} from "../types/applet"
|
|
26
26
|
import {HardwareRequirement, HardwareRequirementLevel, HardwareType} from "../types"
|
|
27
|
-
import {
|
|
27
|
+
import {configuredDevHost} from "../utils/configuredDevHost"
|
|
28
28
|
import {storage} from "../utils/storage/storage"
|
|
29
29
|
import {printDirectory} from "../utils/storage/zip"
|
|
30
30
|
import {checkManifestVersions} from "./manifestVersionGate"
|
|
31
|
+
import {normalizeManifestActions} from "./manifestActions"
|
|
31
32
|
import {miniappRunningRegistry} from "./MiniappRunningRegistry"
|
|
32
33
|
|
|
34
|
+
export {normalizeManifestActions} from "./manifestActions"
|
|
35
|
+
|
|
33
36
|
const ALLOWED_PERMISSION_TYPES: ReadonlySet<AppPermissionType> = new Set<AppPermissionType>([
|
|
34
37
|
"MICROPHONE",
|
|
35
38
|
"CAMERA",
|
|
@@ -73,29 +76,6 @@ function normalizeManifestType(raw: unknown): AppletType {
|
|
|
73
76
|
return raw === "background" || raw === "system_dashboard" || raw === "standard" ? raw : "standard"
|
|
74
77
|
}
|
|
75
78
|
|
|
76
|
-
/**
|
|
77
|
-
* Normalize a manifest's `actions` into DeclaredAction[]. Defensive — keeps only
|
|
78
|
-
* well-formed `{id, description}` entries (installed/dev bundles may be
|
|
79
|
-
* malformed). Shared by installed (disk) and dev-sideload projection so both
|
|
80
|
-
* surface declared actions to session.miniapps.list + the invoke gate.
|
|
81
|
-
*/
|
|
82
|
-
export function normalizeManifestActions(raw: unknown): DeclaredAction[] {
|
|
83
|
-
if (!Array.isArray(raw)) return []
|
|
84
|
-
const out: DeclaredAction[] = []
|
|
85
|
-
for (const a of raw as Array<{id?: unknown; description?: unknown; parameters?: unknown}>) {
|
|
86
|
-
if (a && typeof a.id === "string" && typeof a.description === "string") {
|
|
87
|
-
out.push({
|
|
88
|
-
id: a.id,
|
|
89
|
-
description: a.description,
|
|
90
|
-
...(a.parameters && typeof a.parameters === "object"
|
|
91
|
-
? {parameters: a.parameters as Record<string, unknown>}
|
|
92
|
-
: {}),
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return out
|
|
97
|
-
}
|
|
98
|
-
|
|
99
79
|
/**
|
|
100
80
|
* Convert declared hardwareRequirements from a miniapp.json manifest into
|
|
101
81
|
* runtime `HardwareRequirement[]`, always appending `{EXIST, REQUIRED}` so
|
|
@@ -159,6 +139,17 @@ interface InstalledLma {
|
|
|
159
139
|
versions: Record<string, InstalledInfo>
|
|
160
140
|
}
|
|
161
141
|
|
|
142
|
+
export interface MiniappReleaseIdentity {
|
|
143
|
+
source: "direct_download" | "bundled_asset" | "preinstalled_registry" | "dev_snapshot"
|
|
144
|
+
releaseId?: string
|
|
145
|
+
bundleSha256?: string
|
|
146
|
+
channel?: string
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function releaseIdentityKey(packageName: string, version: string): string {
|
|
150
|
+
return `miniapp_release_identity:${packageName}:${version}`
|
|
151
|
+
}
|
|
152
|
+
|
|
162
153
|
/**
|
|
163
154
|
* Download a miniapp zip from `url` into the cache and return its local path.
|
|
164
155
|
*
|
|
@@ -451,11 +442,18 @@ class AppRegistry {
|
|
|
451
442
|
* of `manifest.version`. The dev caching path uses `dev-<ms>` so multiple
|
|
452
443
|
* snapshots can coexist alongside semver-installed versions.
|
|
453
444
|
*/
|
|
454
|
-
public installFromUrl(
|
|
445
|
+
public installFromUrl(
|
|
446
|
+
url: string,
|
|
447
|
+
opts?: {versionOverride?: string; releaseIdentity?: MiniappReleaseIdentity},
|
|
448
|
+
): AsyncResult<void, Error> {
|
|
455
449
|
return Res.try_async(async () => {
|
|
456
450
|
const {packageName, version} = await downloadAndInstallMiniApp(url, opts?.versionOverride)
|
|
457
451
|
console.log("APP_REGISTRY: Downloaded and installed mini app")
|
|
458
|
-
this.finalizeInstall(
|
|
452
|
+
this.finalizeInstall(
|
|
453
|
+
packageName,
|
|
454
|
+
version,
|
|
455
|
+
opts?.releaseIdentity ?? {source: version.startsWith("dev-") ? "dev_snapshot" : "direct_download"},
|
|
456
|
+
)
|
|
459
457
|
})
|
|
460
458
|
}
|
|
461
459
|
|
|
@@ -468,12 +466,12 @@ class AppRegistry {
|
|
|
468
466
|
*/
|
|
469
467
|
public installFromLocalZip(
|
|
470
468
|
zipPath: string,
|
|
471
|
-
opts?: {versionOverride?: string},
|
|
469
|
+
opts?: {versionOverride?: string; releaseIdentity?: MiniappReleaseIdentity},
|
|
472
470
|
): AsyncResult<{packageName: string; version: string}, Error> {
|
|
473
471
|
return Res.try_async(async () => {
|
|
474
472
|
const {packageName, version} = await unpackMiniApp(zipPath, opts?.versionOverride)
|
|
475
473
|
console.log("APP_REGISTRY: Installed mini app from local zip")
|
|
476
|
-
this.finalizeInstall(packageName, version)
|
|
474
|
+
this.finalizeInstall(packageName, version, opts?.releaseIdentity ?? {source: "bundled_asset"})
|
|
477
475
|
return {packageName, version}
|
|
478
476
|
})
|
|
479
477
|
}
|
|
@@ -483,7 +481,7 @@ class AppRegistry {
|
|
|
483
481
|
* artifacts on release installs, point the active-version at the just-
|
|
484
482
|
* installed bundle, and notify subscribers to refresh.
|
|
485
483
|
*/
|
|
486
|
-
private finalizeInstall(packageName: string, version: string): void {
|
|
484
|
+
private finalizeInstall(packageName: string, version: string, releaseIdentity: MiniappReleaseIdentity): void {
|
|
487
485
|
// If this is a release install (semver, not dev-*) of a package that
|
|
488
486
|
// currently has dev-* snapshots, clear the dev state so the swap to
|
|
489
487
|
// "released" is clean. Otherwise the dev version would keep winning
|
|
@@ -495,10 +493,16 @@ class AppRegistry {
|
|
|
495
493
|
}
|
|
496
494
|
|
|
497
495
|
this.setActiveVersion(packageName, version)
|
|
496
|
+
storage.save(releaseIdentityKey(packageName, version), releaseIdentity)
|
|
498
497
|
this.refreshNeeded = true
|
|
499
498
|
this.notify()
|
|
500
499
|
}
|
|
501
500
|
|
|
501
|
+
public getReleaseIdentity(packageName: string, version: string): MiniappReleaseIdentity | null {
|
|
502
|
+
const result = storage.load<MiniappReleaseIdentity>(releaseIdentityKey(packageName, version))
|
|
503
|
+
return result.is_ok() ? result.value : null
|
|
504
|
+
}
|
|
505
|
+
|
|
502
506
|
public installFromJsonUrl(baseUrl: string): AsyncResult<{packageName: string; version: string; name: string}, Error> {
|
|
503
507
|
return Res.try_async(async () => {
|
|
504
508
|
const trimmed = baseUrl.replace(/\/$/, "")
|
|
@@ -534,6 +538,7 @@ class AppRegistry {
|
|
|
534
538
|
for (const item of pkgDir.list()) {
|
|
535
539
|
if (item instanceof Directory && item.name.startsWith("dev-")) {
|
|
536
540
|
try {
|
|
541
|
+
storage.remove(releaseIdentityKey(packageName, item.name))
|
|
537
542
|
item.delete()
|
|
538
543
|
} catch (e) {
|
|
539
544
|
console.warn(`APP_REGISTRY: failed to delete ${item.name}:`, e)
|
|
@@ -546,17 +551,12 @@ class AppRegistry {
|
|
|
546
551
|
}
|
|
547
552
|
storage.remove(`${packageName}_dev_url`)
|
|
548
553
|
storage.remove(`${packageName}_dev_port`)
|
|
554
|
+
storage.remove(`${packageName}_dev_mdns`)
|
|
549
555
|
storage.remove(`${packageName}_dev_last_reachable`)
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
|
|
554
|
-
// Only do this when we're actually touching the dev slot: either the dev package itself, or the
|
|
555
|
-
// real manifest package currently occupying the slot. Otherwise a release install/uninstall of
|
|
556
|
-
// an UNRELATED package would wipe the active dev tile.
|
|
557
|
-
if (packageName === DEV_APP_PACKAGE_NAME || packageName === getDevAppSourcePackage()) {
|
|
558
|
-
unregisterDevApp()
|
|
559
|
-
}
|
|
556
|
+
// HTTP-direct dev miniapps are indexed by their real package name. A
|
|
557
|
+
// release install/uninstall of that same package should remove only its
|
|
558
|
+
// dev tile; unrelated dev miniapps must remain available.
|
|
559
|
+
if (readDevAppRecord(packageName)) unregisterDevApp(packageName)
|
|
560
560
|
}
|
|
561
561
|
|
|
562
562
|
/**
|
|
@@ -594,12 +594,16 @@ class AppRegistry {
|
|
|
594
594
|
// Guard exists: a dev miniapp loads over HTTP and has no on-disk dir,
|
|
595
595
|
// so an unconditional delete() would throw and abort the cleanup below.
|
|
596
596
|
if (lmaDir.exists) lmaDir.delete()
|
|
597
|
+
storage.remove(releaseIdentityKey(packageName, version))
|
|
597
598
|
console.log("APP_REGISTRY: Uninstalled mini app version", version)
|
|
598
599
|
const packageDir = new Directory(Paths.document, "lmas", packageName)
|
|
599
600
|
if (packageDir.exists && packageDir.list().length === 0) {
|
|
600
601
|
packageDir.delete()
|
|
601
602
|
}
|
|
602
603
|
} else {
|
|
604
|
+
for (const installedVersion of this.getInstalledVersions(packageName)) {
|
|
605
|
+
storage.remove(releaseIdentityKey(packageName, installedVersion))
|
|
606
|
+
}
|
|
603
607
|
const packageDir = new Directory(Paths.document, "lmas", packageName)
|
|
604
608
|
if (packageDir.exists) {
|
|
605
609
|
packageDir.delete()
|
|
@@ -698,25 +702,21 @@ class AppRegistry {
|
|
|
698
702
|
return out
|
|
699
703
|
}
|
|
700
704
|
|
|
701
|
-
/**
|
|
702
|
-
* Read the lmas/ tree and return one ClientApp per installed package,
|
|
703
|
-
* picking each package's active version. The store/host overlays runtime
|
|
704
|
-
* state (loading, hidden, compatibility) on top of these.
|
|
705
|
-
*
|
|
706
|
-
* `running` reflects MiniappHost mount state via miniappRunningRegistry.
|
|
707
|
-
*/
|
|
708
705
|
/**
|
|
709
706
|
* Merge disk-derived apps with the projected dev + offline layers,
|
|
710
|
-
* de-duping by packageName.
|
|
711
|
-
*
|
|
712
|
-
*
|
|
707
|
+
* de-duping by packageName. An active dev registration wins over an older
|
|
708
|
+
* disk install of the same package; installing a release clears that dev
|
|
709
|
+
* registration in finalizeInstall. Native offline apps keep top priority.
|
|
713
710
|
*/
|
|
714
711
|
private mergeProjectedApps(diskApps: ClientApp[]): ClientApp[] {
|
|
715
|
-
const seen = new Set(diskApps.map((a) => a.packageName))
|
|
716
712
|
const offline = this.projectOfflineApps()
|
|
717
|
-
|
|
718
|
-
const dev = this.projectDevApps().filter((
|
|
719
|
-
|
|
713
|
+
const offlinePackages = new Set(offline.map((app) => app.packageName))
|
|
714
|
+
const dev = this.projectDevApps().filter((app) => !offlinePackages.has(app.packageName))
|
|
715
|
+
const devPackages = new Set(dev.map((app) => app.packageName))
|
|
716
|
+
const installed = diskApps.filter(
|
|
717
|
+
(app) => !offlinePackages.has(app.packageName) && !devPackages.has(app.packageName),
|
|
718
|
+
)
|
|
719
|
+
return [...installed, ...dev, ...offline]
|
|
720
720
|
}
|
|
721
721
|
|
|
722
722
|
public async getInstalledMiniapps(): Promise<ClientApp[]> {
|
|
@@ -742,7 +742,7 @@ class AppRegistry {
|
|
|
742
742
|
permissions?: Array<string | {type: string; required?: boolean; description?: string}>
|
|
743
743
|
hardwareRequirements?: Array<{type: string; level: string; description?: string}>
|
|
744
744
|
type?: string
|
|
745
|
-
actions?: Array<{id?: unknown; description?: unknown; parameters?: unknown}>
|
|
745
|
+
actions?: Array<{id?: unknown; description?: unknown; parameters?: unknown; outputSchema?: unknown}>
|
|
746
746
|
} | null
|
|
747
747
|
|
|
748
748
|
const permissions = normalizeManifestPermissions(manifest?.permissions)
|
|
@@ -871,6 +871,22 @@ class AppRegistry {
|
|
|
871
871
|
this.notify()
|
|
872
872
|
}
|
|
873
873
|
|
|
874
|
+
/**
|
|
875
|
+
* Update whether a registered offline app is projected into launcher UIs.
|
|
876
|
+
*
|
|
877
|
+
* Offline apps are registered once at host startup, so settings-backed
|
|
878
|
+
* visibility changes need to update the projection without reinstalling or
|
|
879
|
+
* duplicating the app. No-op when the app is missing or already matches.
|
|
880
|
+
*/
|
|
881
|
+
public setOfflineAppHidden(packageName: string, hidden: boolean): void {
|
|
882
|
+
const app = this.offlineApps.find((candidate) => candidate.packageName === packageName)
|
|
883
|
+
if (!app || app.hidden === hidden) return
|
|
884
|
+
|
|
885
|
+
app.hidden = hidden
|
|
886
|
+
this.refreshNeeded = true
|
|
887
|
+
this.notify()
|
|
888
|
+
}
|
|
889
|
+
|
|
874
890
|
/**
|
|
875
891
|
* Registered as needing the on-device STT model before it can start (the
|
|
876
892
|
* host declares this per offline app; the apps store gates start() on it).
|
|
@@ -940,43 +956,30 @@ export interface DevAppRecord {
|
|
|
940
956
|
iconUrl: string
|
|
941
957
|
devUrl: string
|
|
942
958
|
devPort?: number
|
|
959
|
+
/**
|
|
960
|
+
* Bonjour / mDNS hostname from the QR (`ComputerName.local`). Used as a
|
|
961
|
+
* failover host when the raw LAN IP in `devUrl` goes stale after a Wi-Fi
|
|
962
|
+
* change — phones that resolve `.local` can relaunch without re-scanning.
|
|
963
|
+
*/
|
|
964
|
+
mdnsHost?: string
|
|
943
965
|
type?: AppletType
|
|
944
966
|
permissions?: Array<string | {type: string; required?: boolean; description?: string}>
|
|
945
967
|
hardwareRequirements?: Array<{type: string; level: string; description?: string}>
|
|
946
968
|
/** Manifest-declared actions — so dev-sideloaded miniapps can be invoked too. */
|
|
947
|
-
actions?: Array<{id?: unknown; description?: unknown; parameters?: unknown}>
|
|
948
|
-
/**
|
|
949
|
-
* The dev miniapp's real manifest package name. `packageName` is overwritten to
|
|
950
|
-
* {@link DEV_APP_PACKAGE_NAME} so the launch chain routes consistently, so this field
|
|
951
|
-
* preserves the original so install/uninstall of OTHER packages don't wipe the dev slot.
|
|
952
|
-
*/
|
|
969
|
+
actions?: Array<{id?: unknown; description?: unknown; parameters?: unknown; outputSchema?: unknown}>
|
|
970
|
+
/** Legacy single-slot migration field. New records use the real packageName directly. */
|
|
953
971
|
sourcePackageName?: string
|
|
954
972
|
/**
|
|
955
973
|
* Short-lived Core-verifiable proof emitted by `mentra dev`. This lets the
|
|
956
|
-
*
|
|
957
|
-
*
|
|
974
|
+
* dev runtime request auto-auth for the manifest package without letting
|
|
975
|
+
* arbitrary dev URLs claim any package name.
|
|
958
976
|
*/
|
|
959
977
|
devAttestation?: string
|
|
960
978
|
}
|
|
961
979
|
|
|
962
980
|
const DEV_APPS_INDEX_KEY = "dev_apps_index"
|
|
981
|
+
const DEV_APP_ICONS_DIR = "dev-miniapp-icons"
|
|
963
982
|
|
|
964
|
-
function configuredDevHost(): string | undefined {
|
|
965
|
-
// Explicit escape hatch first; otherwise the host-injected Metro host (the
|
|
966
|
-
// address this dev bundle was served from — always current for the network
|
|
967
|
-
// the phone is on). Deliberately NOT the EXPO_PUBLIC_CLOUD_* URLs: those are
|
|
968
|
-
// cloud endpoints, a different machine entirely from the laptop running the
|
|
969
|
-
// miniapp dev server, and rewriting a dev URL to a cloud host would break it.
|
|
970
|
-
const explicit = process.env.EXPO_PUBLIC_LOCAL_MINIAPP_HOST
|
|
971
|
-
if (explicit) {
|
|
972
|
-
try {
|
|
973
|
-
return new URL(explicit).hostname
|
|
974
|
-
} catch {
|
|
975
|
-
if (/^[\w.-]+$/.test(explicit)) return explicit
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
return getConfigValues().devServerHost?.()
|
|
979
|
-
}
|
|
980
983
|
|
|
981
984
|
function isPrivateLanHost(hostname: string): boolean {
|
|
982
985
|
return (
|
|
@@ -1008,72 +1011,173 @@ function normalizeDevAppRecord(record: DevAppRecord): DevAppRecord {
|
|
|
1008
1011
|
return devUrl === record.devUrl && iconUrl === record.iconUrl ? record : {...record, devUrl, iconUrl}
|
|
1009
1012
|
}
|
|
1010
1013
|
|
|
1011
|
-
/**
|
|
1012
|
-
* The one and only package name a dev miniapp is registered under.
|
|
1013
|
-
*
|
|
1014
|
-
* There is a SINGLE dev slot: scanning a new QR (or entering a new dev URL)
|
|
1015
|
-
* replaces the previous dev app rather than adding a second tile. Because the
|
|
1016
|
-
* whole launch chain — JSContext registration, UI-router binding,
|
|
1017
|
-
* setForeground, dev_url/dev_port storage keys, respawn-bg lookup — keys on
|
|
1018
|
-
* this package name, every consumer MUST use `DEV_APP_PACKAGE_NAME` (not the
|
|
1019
|
-
* manifest's real packageName) so messages route consistently. Mixing the two
|
|
1020
|
-
* was the cause of the "CONNECT_ACK timeout" — the tile said `com.dev` while
|
|
1021
|
-
* the dev URL/port and foreground target used the manifest name.
|
|
1022
|
-
*/
|
|
1014
|
+
/** Legacy package used by builds that supported only one dev miniapp. */
|
|
1023
1015
|
export const DEV_APP_PACKAGE_NAME = "com.dev"
|
|
1024
1016
|
export const DEV_APP_NAME = "Dev"
|
|
1025
1017
|
|
|
1026
1018
|
/**
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
*
|
|
1030
|
-
* `*_dev_url` / `*_dev_port` keys under the manifest's real package name.
|
|
1031
|
-
*
|
|
1032
|
-
* Callers pass the manifest's REAL packageName/name. Only the packageName is
|
|
1033
|
-
* forced to {@link DEV_APP_PACKAGE_NAME} so the home tile and launch chain key
|
|
1034
|
-
* on the single dev slot (the real package survives in `sourcePackageName` for
|
|
1035
|
-
* clearDevArtifacts). The name + icon are kept as-is so the home tile reflects
|
|
1036
|
-
* the actual dev miniapp — marked as dev by the {@link DevMiniappBadge} dot
|
|
1037
|
-
* rather than renamed to a generic "Dev" tile.
|
|
1019
|
+
* Copy a dev-server icon into Documents so the tile remains branded after the
|
|
1020
|
+
* laptop/server disappears. A failed download is non-fatal: the remote URL is
|
|
1021
|
+
* retained and can still render while the server is reachable.
|
|
1038
1022
|
*/
|
|
1039
|
-
|
|
1023
|
+
async function cacheDevAppIcon(packageName: string, iconUrl: string): Promise<string> {
|
|
1024
|
+
if (!/^https?:\/\//.test(iconUrl)) return iconUrl
|
|
1025
|
+
|
|
1026
|
+
try {
|
|
1027
|
+
const dir = new Directory(Paths.document, DEV_APP_ICONS_DIR)
|
|
1028
|
+
if (!dir.exists) dir.create({intermediates: true})
|
|
1029
|
+
|
|
1030
|
+
const safePackageName = packageName.replace(/[^a-zA-Z0-9._-]/g, "_")
|
|
1031
|
+
let extension = ".png"
|
|
1032
|
+
try {
|
|
1033
|
+
const match = new URL(iconUrl).pathname.match(/\.(png|jpe?g|webp|gif|svg)$/i)
|
|
1034
|
+
if (match) extension = `.${match[1].toLowerCase()}`
|
|
1035
|
+
} catch {
|
|
1036
|
+
// Keep the decoder-friendly .png fallback; image loaders sniff content.
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
const target = new File(dir, `${safePackageName}${extension}`)
|
|
1040
|
+
const downloaded = await File.downloadFileAsync(iconUrl, target, {idempotent: true})
|
|
1041
|
+
|
|
1042
|
+
// Only remove older extensions AFTER the replacement is safely on disk;
|
|
1043
|
+
// a broken icon URL must not destroy the last known-good cached logo.
|
|
1044
|
+
for (const item of dir.list()) {
|
|
1045
|
+
if (item instanceof File && item.uri !== downloaded.uri && item.name.startsWith(`${safePackageName}.`)) {
|
|
1046
|
+
try {
|
|
1047
|
+
item.delete()
|
|
1048
|
+
} catch {
|
|
1049
|
+
// Best effort; the current icon has already been persisted.
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return downloaded.uri
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
console.warn(`APP_REGISTRY: failed to cache dev icon for ${packageName}:`, error)
|
|
1056
|
+
return readDevAppRecord(packageName)?.iconUrl ?? iconUrl
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
function removeDevRecordKeys(packageName: string): void {
|
|
1061
|
+
const existing = readDevAppRecord(packageName)
|
|
1062
|
+
if (existing?.iconUrl.startsWith("file://")) {
|
|
1063
|
+
try {
|
|
1064
|
+
const icon = new File(existing.iconUrl)
|
|
1065
|
+
if (icon.exists) icon.delete()
|
|
1066
|
+
} catch (error) {
|
|
1067
|
+
console.warn(`APP_REGISTRY: failed to delete dev icon for ${packageName}:`, error)
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
storage.remove(`${packageName}_dev_meta`)
|
|
1071
|
+
storage.remove(`${packageName}_dev_url`)
|
|
1072
|
+
storage.remove(`${packageName}_dev_port`)
|
|
1073
|
+
storage.remove(`${packageName}_dev_mdns`)
|
|
1074
|
+
storage.remove(`${packageName}_dev_last_reachable`)
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
function readDevAppRecord(packageName: string): DevAppRecord | null {
|
|
1078
|
+
const res = storage.load<string>(`${packageName}_dev_meta`)
|
|
1079
|
+
if (!res.is_ok()) return null
|
|
1080
|
+
try {
|
|
1081
|
+
return JSON.parse(res.value) as DevAppRecord
|
|
1082
|
+
} catch {
|
|
1083
|
+
return null
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
/** Move the historical `com.dev` record onto its real manifest package key. */
|
|
1088
|
+
function migrateLegacyDevSlot(): void {
|
|
1089
|
+
const legacy = readDevAppRecord(DEV_APP_PACKAGE_NAME)
|
|
1090
|
+
const targetPackage = legacy?.sourcePackageName?.trim()
|
|
1091
|
+
if (!legacy || !targetPackage || targetPackage === DEV_APP_PACKAGE_NAME) return
|
|
1092
|
+
|
|
1093
|
+
const existingTarget = readDevAppRecord(targetPackage)
|
|
1094
|
+
const migrated: DevAppRecord = existingTarget ?? {
|
|
1095
|
+
...legacy,
|
|
1096
|
+
packageName: targetPackage,
|
|
1097
|
+
sourcePackageName: targetPackage,
|
|
1098
|
+
}
|
|
1099
|
+
if (!existingTarget) storage.save(`${targetPackage}_dev_meta`, JSON.stringify(migrated))
|
|
1100
|
+
|
|
1101
|
+
const legacyUrl = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_url`)
|
|
1102
|
+
const targetUrl = storage.load<string>(`${targetPackage}_dev_url`)
|
|
1103
|
+
if (!targetUrl.is_ok()) {
|
|
1104
|
+
storage.save(`${targetPackage}_dev_url`, legacyUrl.is_ok() ? legacyUrl.value : migrated.devUrl)
|
|
1105
|
+
}
|
|
1106
|
+
const legacyPort = storage.load<number>(`${DEV_APP_PACKAGE_NAME}_dev_port`)
|
|
1107
|
+
const targetPort = storage.load<number>(`${targetPackage}_dev_port`)
|
|
1108
|
+
if (!targetPort.is_ok()) {
|
|
1109
|
+
const port = migrated.devPort ?? (legacyPort.is_ok() ? legacyPort.value : undefined)
|
|
1110
|
+
if (typeof port === "number" && Number.isFinite(port)) storage.save(`${targetPackage}_dev_port`, port)
|
|
1111
|
+
}
|
|
1112
|
+
const legacyMdns = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_mdns`)
|
|
1113
|
+
const targetMdns = storage.load<string>(`${targetPackage}_dev_mdns`)
|
|
1114
|
+
if (!targetMdns.is_ok() && legacyMdns.is_ok() && legacyMdns.value.trim()) {
|
|
1115
|
+
storage.save(`${targetPackage}_dev_mdns`, legacyMdns.value.trim())
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_meta`)
|
|
1119
|
+
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_url`)
|
|
1120
|
+
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_port`)
|
|
1121
|
+
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_mdns`)
|
|
1122
|
+
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_last_reachable`)
|
|
1123
|
+
|
|
1124
|
+
const index = Array.from(new Set(getDevAppIndex().map((pkg) => (pkg === DEV_APP_PACKAGE_NAME ? targetPackage : pkg))))
|
|
1125
|
+
storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(index))
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
function readStoredMdnsHost(packageName: string): string | undefined {
|
|
1129
|
+
const res = storage.load<string>(`${packageName}_dev_mdns`)
|
|
1130
|
+
if (!res.is_ok()) return undefined
|
|
1131
|
+
return res.value.trim() || undefined
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
/**
|
|
1135
|
+
* Register or update one dev miniapp under its real manifest package. Different
|
|
1136
|
+
* package names coexist; rescanning the same package updates that package only.
|
|
1137
|
+
*/
|
|
1138
|
+
export async function registerDevApp(record: DevAppRecord): Promise<void> {
|
|
1139
|
+
migrateLegacyDevSlot()
|
|
1140
|
+
const packageName = record.packageName.trim()
|
|
1141
|
+
if (!packageName) throw new Error("Dev miniapp manifest is missing packageName")
|
|
1142
|
+
|
|
1143
|
+
const iconUrl = await cacheDevAppIcon(packageName, record.iconUrl)
|
|
1144
|
+
// Relaunch paths (developer-URL screen, loadDevMiniapp) omit mdnsHost, so an
|
|
1145
|
+
// omitted field keeps whatever the QR scan stored instead of wiping the
|
|
1146
|
+
// `.local` failover host.
|
|
1147
|
+
const mdnsHost =
|
|
1148
|
+
record.mdnsHost !== undefined ? record.mdnsHost.trim() || undefined : readStoredMdnsHost(packageName)
|
|
1040
1149
|
const devRecord: DevAppRecord = {
|
|
1041
1150
|
...record,
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
// actually targets the dev slot.
|
|
1045
|
-
sourcePackageName: record.sourcePackageName ?? record.packageName,
|
|
1046
|
-
packageName: DEV_APP_PACKAGE_NAME,
|
|
1047
|
-
// Keep the manifest's real name + icon (display-only; routing keys on
|
|
1048
|
-
// packageName). Fall back to DEV_APP_NAME only if a caller omitted the name.
|
|
1151
|
+
packageName,
|
|
1152
|
+
sourcePackageName: packageName,
|
|
1049
1153
|
name: record.name || DEV_APP_NAME,
|
|
1050
|
-
iconUrl
|
|
1154
|
+
iconUrl,
|
|
1155
|
+
mdnsHost,
|
|
1051
1156
|
}
|
|
1052
|
-
storage.save(`${
|
|
1053
|
-
|
|
1054
|
-
// respawn-bg) reads these keys under DEV_APP_PACKAGE_NAME — persist them
|
|
1055
|
-
// here so callers can't key them on the wrong (real) package name.
|
|
1056
|
-
storage.save(`${DEV_APP_PACKAGE_NAME}_dev_url`, record.devUrl)
|
|
1157
|
+
storage.save(`${packageName}_dev_meta`, JSON.stringify(devRecord))
|
|
1158
|
+
storage.save(`${packageName}_dev_url`, record.devUrl)
|
|
1057
1159
|
if (typeof record.devPort === "number" && Number.isFinite(record.devPort)) {
|
|
1058
|
-
storage.save(`${
|
|
1160
|
+
storage.save(`${packageName}_dev_port`, record.devPort)
|
|
1161
|
+
} else {
|
|
1162
|
+
storage.remove(`${packageName}_dev_port`)
|
|
1163
|
+
}
|
|
1164
|
+
if (mdnsHost) {
|
|
1165
|
+
storage.save(`${packageName}_dev_mdns`, mdnsHost)
|
|
1059
1166
|
} else {
|
|
1060
|
-
storage.remove(`${
|
|
1167
|
+
storage.remove(`${packageName}_dev_mdns`)
|
|
1061
1168
|
}
|
|
1062
1169
|
const idx = getDevAppIndex()
|
|
1063
|
-
if (!idx.includes(
|
|
1064
|
-
idx.push(
|
|
1170
|
+
if (!idx.includes(packageName)) {
|
|
1171
|
+
idx.push(packageName)
|
|
1065
1172
|
storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(idx))
|
|
1066
1173
|
}
|
|
1067
1174
|
appRegistry.markRefreshNeeded()
|
|
1068
1175
|
}
|
|
1069
1176
|
|
|
1070
|
-
/** Drop
|
|
1071
|
-
export function unregisterDevApp(): void {
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_port`)
|
|
1075
|
-
storage.remove(`${DEV_APP_PACKAGE_NAME}_dev_last_reachable`)
|
|
1076
|
-
const idx = getDevAppIndex().filter((p) => p !== DEV_APP_PACKAGE_NAME)
|
|
1177
|
+
/** Drop one dev miniapp's metadata, routing keys, and cached icon. */
|
|
1178
|
+
export function unregisterDevApp(packageName = DEV_APP_PACKAGE_NAME): void {
|
|
1179
|
+
removeDevRecordKeys(packageName)
|
|
1180
|
+
const idx = getDevAppIndex().filter((p) => p !== packageName)
|
|
1077
1181
|
storage.save(DEV_APPS_INDEX_KEY, JSON.stringify(idx))
|
|
1078
1182
|
appRegistry.markRefreshNeeded()
|
|
1079
1183
|
}
|
|
@@ -1089,33 +1193,20 @@ function getDevAppIndex(): string[] {
|
|
|
1089
1193
|
}
|
|
1090
1194
|
}
|
|
1091
1195
|
|
|
1092
|
-
/**
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
const res = storage.load<string>(`${DEV_APP_PACKAGE_NAME}_dev_meta`)
|
|
1098
|
-
if (!res.is_ok()) return null
|
|
1099
|
-
try {
|
|
1100
|
-
const rec = JSON.parse(res.value) as DevAppRecord
|
|
1101
|
-
return rec.sourcePackageName ?? null
|
|
1102
|
-
} catch {
|
|
1103
|
-
return null
|
|
1104
|
-
}
|
|
1196
|
+
/** Resolve the manifest package for a dev runtime (including the legacy slot). */
|
|
1197
|
+
export function getDevAppSourcePackage(packageName = DEV_APP_PACKAGE_NAME): string | null {
|
|
1198
|
+
migrateLegacyDevSlot()
|
|
1199
|
+
const rec = readDevAppRecord(packageName)
|
|
1200
|
+
return rec?.sourcePackageName ?? rec?.packageName ?? null
|
|
1105
1201
|
}
|
|
1106
1202
|
|
|
1107
|
-
export function getDevAppAttestation(): string | null {
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
try {
|
|
1111
|
-
const rec = JSON.parse(res.value) as DevAppRecord
|
|
1112
|
-
return rec.devAttestation ?? null
|
|
1113
|
-
} catch {
|
|
1114
|
-
return null
|
|
1115
|
-
}
|
|
1203
|
+
export function getDevAppAttestation(packageName = DEV_APP_PACKAGE_NAME): string | null {
|
|
1204
|
+
migrateLegacyDevSlot()
|
|
1205
|
+
return readDevAppRecord(packageName)?.devAttestation ?? null
|
|
1116
1206
|
}
|
|
1117
1207
|
|
|
1118
1208
|
export function getDevAppRecords(): DevAppRecord[] {
|
|
1209
|
+
migrateLegacyDevSlot()
|
|
1119
1210
|
const out: DevAppRecord[] = []
|
|
1120
1211
|
for (const pkg of getDevAppIndex()) {
|
|
1121
1212
|
const res = storage.load<string>(`${pkg}_dev_meta`)
|