@mentra/engine 0.1.0-beta.0
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 +79 -0
- package/build/devtools.d.ts +11 -0
- package/build/devtools.d.ts.map +1 -0
- package/build/devtools.js +13 -0
- package/build/devtools.js.map +1 -0
- package/build/engine.d.ts +261 -0
- package/build/engine.d.ts.map +1 -0
- package/build/engine.js +170 -0
- package/build/engine.js.map +1 -0
- package/build/facades/dev.d.ts +58 -0
- package/build/facades/dev.d.ts.map +1 -0
- package/build/facades/dev.js +189 -0
- package/build/facades/dev.js.map +1 -0
- package/build/facades/display.d.ts +21 -0
- package/build/facades/display.d.ts.map +1 -0
- package/build/facades/display.js +17 -0
- package/build/facades/display.js.map +1 -0
- package/build/facades/displayMirror.d.ts +15 -0
- package/build/facades/displayMirror.d.ts.map +1 -0
- package/build/facades/displayMirror.js +29 -0
- package/build/facades/displayMirror.js.map +1 -0
- package/build/facades/gallery.d.ts +62 -0
- package/build/facades/gallery.d.ts.map +1 -0
- package/build/facades/gallery.js +61 -0
- package/build/facades/gallery.js.map +1 -0
- package/build/facades/glasses.d.ts +141 -0
- package/build/facades/glasses.d.ts.map +1 -0
- package/build/facades/glasses.js +199 -0
- package/build/facades/glasses.js.map +1 -0
- package/build/facades/glassesSettings.d.ts +13 -0
- package/build/facades/glassesSettings.d.ts.map +1 -0
- package/build/facades/glassesSettings.js +54 -0
- package/build/facades/glassesSettings.js.map +1 -0
- package/build/facades/glassesWifi.d.ts +25 -0
- package/build/facades/glassesWifi.d.ts.map +1 -0
- package/build/facades/glassesWifi.js +57 -0
- package/build/facades/glassesWifi.js.map +1 -0
- package/build/facades/miniapps.d.ts +43 -0
- package/build/facades/miniapps.d.ts.map +1 -0
- package/build/facades/miniapps.js +49 -0
- package/build/facades/miniapps.js.map +1 -0
- package/build/facades/notifications.d.ts +13 -0
- package/build/facades/notifications.d.ts.map +1 -0
- package/build/facades/notifications.js +12 -0
- package/build/facades/notifications.js.map +1 -0
- package/build/facades/ota.d.ts +103 -0
- package/build/facades/ota.d.ts.map +1 -0
- package/build/facades/ota.js +156 -0
- package/build/facades/ota.js.map +1 -0
- package/build/facades/pairing.d.ts +114 -0
- package/build/facades/pairing.d.ts.map +1 -0
- package/build/facades/pairing.js +275 -0
- package/build/facades/pairing.js.map +1 -0
- package/build/facades/permissions.d.ts +33 -0
- package/build/facades/permissions.d.ts.map +1 -0
- package/build/facades/permissions.js +155 -0
- package/build/facades/permissions.js.map +1 -0
- package/build/facades/phoneNotifications.d.ts +21 -0
- package/build/facades/phoneNotifications.d.ts.map +1 -0
- package/build/facades/phoneNotifications.js +51 -0
- package/build/facades/phoneNotifications.js.map +1 -0
- package/build/facades/reports.d.ts +36 -0
- package/build/facades/reports.d.ts.map +1 -0
- package/build/facades/reports.js +134 -0
- package/build/facades/reports.js.map +1 -0
- package/build/facades/session.d.ts +21 -0
- package/build/facades/session.d.ts.map +1 -0
- package/build/facades/session.js +52 -0
- package/build/facades/session.js.map +1 -0
- package/build/facades/settings.d.ts +37 -0
- package/build/facades/settings.d.ts.map +1 -0
- package/build/facades/settings.js +55 -0
- package/build/facades/settings.js.map +1 -0
- package/build/facades/speech.d.ts +30 -0
- package/build/facades/speech.d.ts.map +1 -0
- package/build/facades/speech.js +37 -0
- package/build/facades/speech.js.map +1 -0
- package/build/index.d.ts +43 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +45 -0
- package/build/index.js.map +1 -0
- package/build/internal.d.ts +67 -0
- package/build/internal.d.ts.map +1 -0
- package/build/internal.js +90 -0
- package/build/internal.js.map +1 -0
- package/build/runtime/bootstrap.d.ts +83 -0
- package/build/runtime/bootstrap.d.ts.map +1 -0
- package/build/runtime/bootstrap.js +56 -0
- package/build/runtime/bootstrap.js.map +1 -0
- package/build/runtime/config.d.ts +146 -0
- package/build/runtime/config.d.ts.map +1 -0
- package/build/runtime/config.js +18 -0
- package/build/runtime/config.js.map +1 -0
- package/build/runtime/streamConfig.d.ts +4 -0
- package/build/runtime/streamConfig.d.ts.map +1 -0
- package/build/runtime/streamConfig.js +38 -0
- package/build/runtime/streamConfig.js.map +1 -0
- package/build/services/AppRegistry.d.ts +269 -0
- package/build/services/AppRegistry.d.ts.map +1 -0
- package/build/services/AppRegistry.js +1079 -0
- package/build/services/AppRegistry.js.map +1 -0
- package/build/services/AudioCloudUplink.d.ts +9 -0
- package/build/services/AudioCloudUplink.d.ts.map +1 -0
- package/build/services/AudioCloudUplink.js +48 -0
- package/build/services/AudioCloudUplink.js.map +1 -0
- package/build/services/AudioPlaybackService.d.ts +175 -0
- package/build/services/AudioPlaybackService.d.ts.map +1 -0
- package/build/services/AudioPlaybackService.js +705 -0
- package/build/services/AudioPlaybackService.js.map +1 -0
- package/build/services/AutomaticReportResult.d.ts +20 -0
- package/build/services/AutomaticReportResult.d.ts.map +1 -0
- package/build/services/AutomaticReportResult.js +29 -0
- package/build/services/AutomaticReportResult.js.map +1 -0
- package/build/services/BlobStore.d.ts +91 -0
- package/build/services/BlobStore.d.ts.map +1 -0
- package/build/services/BlobStore.js +668 -0
- package/build/services/BlobStore.js.map +1 -0
- package/build/services/CaptionsTesterReportService.d.ts +4 -0
- package/build/services/CaptionsTesterReportService.d.ts.map +1 -0
- package/build/services/CaptionsTesterReportService.js +80 -0
- package/build/services/CaptionsTesterReportService.js.map +1 -0
- package/build/services/CloudAudioSubscriptionSync.d.ts +24 -0
- package/build/services/CloudAudioSubscriptionSync.d.ts.map +1 -0
- package/build/services/CloudAudioSubscriptionSync.js +39 -0
- package/build/services/CloudAudioSubscriptionSync.js.map +1 -0
- package/build/services/CloudClientService.d.ts +143 -0
- package/build/services/CloudClientService.d.ts.map +1 -0
- package/build/services/CloudClientService.js +644 -0
- package/build/services/CloudClientService.js.map +1 -0
- package/build/services/CloudTranscriptE2EMetrics.d.ts +4 -0
- package/build/services/CloudTranscriptE2EMetrics.d.ts.map +1 -0
- package/build/services/CloudTranscriptE2EMetrics.js +24 -0
- package/build/services/CloudTranscriptE2EMetrics.js.map +1 -0
- package/build/services/ConnectionCoordinator.d.ts +51 -0
- package/build/services/ConnectionCoordinator.d.ts.map +1 -0
- package/build/services/ConnectionCoordinator.js +34 -0
- package/build/services/ConnectionCoordinator.js.map +1 -0
- package/build/services/DevServerBridge.d.ts +63 -0
- package/build/services/DevServerBridge.d.ts.map +1 -0
- package/build/services/DevServerBridge.js +294 -0
- package/build/services/DevServerBridge.js.map +1 -0
- package/build/services/DeviceEventRouter.d.ts +3 -0
- package/build/services/DeviceEventRouter.d.ts.map +1 -0
- package/build/services/DeviceEventRouter.js +190 -0
- package/build/services/DeviceEventRouter.js.map +1 -0
- package/build/services/DeviceStoreHydration.d.ts +38 -0
- package/build/services/DeviceStoreHydration.d.ts.map +1 -0
- package/build/services/DeviceStoreHydration.js +124 -0
- package/build/services/DeviceStoreHydration.js.map +1 -0
- package/build/services/DisplayProcessor.d.ts +223 -0
- package/build/services/DisplayProcessor.d.ts.map +1 -0
- package/build/services/DisplayProcessor.js +552 -0
- package/build/services/DisplayProcessor.js.map +1 -0
- package/build/services/GlassesReadiness.d.ts +41 -0
- package/build/services/GlassesReadiness.d.ts.map +1 -0
- package/build/services/GlassesReadiness.js +82 -0
- package/build/services/GlassesReadiness.js.map +1 -0
- package/build/services/GlassesSettingsSync.d.ts +33 -0
- package/build/services/GlassesSettingsSync.d.ts.map +1 -0
- package/build/services/GlassesSettingsSync.js +121 -0
- package/build/services/GlassesSettingsSync.js.map +1 -0
- package/build/services/GlassesStatusProjection.d.ts +3 -0
- package/build/services/GlassesStatusProjection.d.ts.map +1 -0
- package/build/services/GlassesStatusProjection.js +65 -0
- package/build/services/GlassesStatusProjection.js.map +1 -0
- package/build/services/HeadingService.d.ts +27 -0
- package/build/services/HeadingService.d.ts.map +1 -0
- package/build/services/HeadingService.js +96 -0
- package/build/services/HeadingService.js.map +1 -0
- package/build/services/LocalDisplayManager.d.ts +139 -0
- package/build/services/LocalDisplayManager.d.ts.map +1 -0
- package/build/services/LocalDisplayManager.js +579 -0
- package/build/services/LocalDisplayManager.js.map +1 -0
- package/build/services/LocalMiniappRuntime.d.ts +439 -0
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -0
- package/build/services/LocalMiniappRuntime.js +3695 -0
- package/build/services/LocalMiniappRuntime.js.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts +57 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.js +137 -0
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -0
- package/build/services/MentraJSCrashController.d.ts +97 -0
- package/build/services/MentraJSCrashController.d.ts.map +1 -0
- package/build/services/MentraJSCrashController.js +138 -0
- package/build/services/MentraJSCrashController.js.map +1 -0
- package/build/services/MentraJSCrashloopReportService.d.ts +9 -0
- package/build/services/MentraJSCrashloopReportService.d.ts.map +1 -0
- package/build/services/MentraJSCrashloopReportService.js +54 -0
- package/build/services/MentraJSCrashloopReportService.js.map +1 -0
- package/build/services/MentraJSLogPipeline.d.ts +87 -0
- package/build/services/MentraJSLogPipeline.d.ts.map +1 -0
- package/build/services/MentraJSLogPipeline.js +137 -0
- package/build/services/MentraJSLogPipeline.js.map +1 -0
- package/build/services/MentraJSRouter.d.ts +203 -0
- package/build/services/MentraJSRouter.d.ts.map +1 -0
- package/build/services/MentraJSRouter.js +480 -0
- package/build/services/MentraJSRouter.js.map +1 -0
- package/build/services/MentraUIRouter.d.ts +137 -0
- package/build/services/MentraUIRouter.d.ts.map +1 -0
- package/build/services/MentraUIRouter.js +210 -0
- package/build/services/MentraUIRouter.js.map +1 -0
- package/build/services/MicStateCoordinator.d.ts +37 -0
- package/build/services/MicStateCoordinator.d.ts.map +1 -0
- package/build/services/MicStateCoordinator.js +81 -0
- package/build/services/MicStateCoordinator.js.map +1 -0
- package/build/services/MiniappEngine.d.ts +31 -0
- package/build/services/MiniappEngine.d.ts.map +1 -0
- package/build/services/MiniappEngine.js +119 -0
- package/build/services/MiniappEngine.js.map +1 -0
- package/build/services/MiniappLauncher.d.ts +129 -0
- package/build/services/MiniappLauncher.d.ts.map +1 -0
- package/build/services/MiniappLauncher.js +291 -0
- package/build/services/MiniappLauncher.js.map +1 -0
- package/build/services/MiniappRunningRegistry.d.ts +24 -0
- package/build/services/MiniappRunningRegistry.d.ts.map +1 -0
- package/build/services/MiniappRunningRegistry.js +52 -0
- package/build/services/MiniappRunningRegistry.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/NavigationHandlers.d.ts +90 -0
- package/build/services/NavigationHandlers.d.ts.map +1 -0
- package/build/services/NavigationHandlers.js +379 -0
- package/build/services/NavigationHandlers.js.map +1 -0
- package/build/services/NavigationService.d.ts +254 -0
- package/build/services/NavigationService.d.ts.map +1 -0
- package/build/services/NavigationService.js +553 -0
- package/build/services/NavigationService.js.map +1 -0
- package/build/services/NotificationsEmitter.d.ts +28 -0
- package/build/services/NotificationsEmitter.d.ts.map +1 -0
- package/build/services/NotificationsEmitter.js +22 -0
- package/build/services/NotificationsEmitter.js.map +1 -0
- package/build/services/OfflineSpeechModelService.d.ts +33 -0
- package/build/services/OfflineSpeechModelService.d.ts.map +1 -0
- package/build/services/OfflineSpeechModelService.js +136 -0
- package/build/services/OfflineSpeechModelService.js.map +1 -0
- package/build/services/OtaInstallCoordinator.d.ts +195 -0
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -0
- package/build/services/OtaInstallCoordinator.js +1047 -0
- package/build/services/OtaInstallCoordinator.js.map +1 -0
- package/build/services/OtaService.d.ts +3 -0
- package/build/services/OtaService.d.ts.map +1 -0
- package/build/services/OtaService.js +65 -0
- package/build/services/OtaService.js.map +1 -0
- package/build/services/OtaUpdateCheckService.d.ts +65 -0
- package/build/services/OtaUpdateCheckService.d.ts.map +1 -0
- package/build/services/OtaUpdateCheckService.js +260 -0
- package/build/services/OtaUpdateCheckService.js.map +1 -0
- package/build/services/PairingIdentity.d.ts +80 -0
- package/build/services/PairingIdentity.d.ts.map +1 -0
- package/build/services/PairingIdentity.js +145 -0
- package/build/services/PairingIdentity.js.map +1 -0
- 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 +24 -0
- package/build/services/PhoneCalendarService.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts +28 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.js +180 -0
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -0
- package/build/services/PhoneLocationService.d.ts +36 -0
- package/build/services/PhoneLocationService.d.ts.map +1 -0
- package/build/services/PhoneLocationService.js +115 -0
- package/build/services/PhoneLocationService.js.map +1 -0
- package/build/services/PhoneNotificationsSync.d.ts +3 -0
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -0
- package/build/services/PhoneNotificationsSync.js +35 -0
- package/build/services/PhoneNotificationsSync.js.map +1 -0
- package/build/services/PhonePhotoCoordinator.d.ts +103 -0
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -0
- package/build/services/PhonePhotoCoordinator.js +326 -0
- package/build/services/PhonePhotoCoordinator.js.map +1 -0
- package/build/services/PhoneStreamCoordinator.d.ts +168 -0
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -0
- package/build/services/PhoneStreamCoordinator.js +632 -0
- package/build/services/PhoneStreamCoordinator.js.map +1 -0
- package/build/services/PhoneVideoCoordinator.d.ts +50 -0
- package/build/services/PhoneVideoCoordinator.d.ts.map +1 -0
- package/build/services/PhoneVideoCoordinator.js +147 -0
- package/build/services/PhoneVideoCoordinator.js.map +1 -0
- package/build/services/STTModelManager.d.ts +65 -0
- package/build/services/STTModelManager.d.ts.map +1 -0
- package/build/services/STTModelManager.js +292 -0
- package/build/services/STTModelManager.js.map +1 -0
- package/build/services/SceneRenderer.d.ts +90 -0
- package/build/services/SceneRenderer.d.ts.map +1 -0
- package/build/services/SceneRenderer.js +248 -0
- package/build/services/SceneRenderer.js.map +1 -0
- 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/StreamLifecycleController.d.ts +67 -0
- package/build/services/StreamLifecycleController.d.ts.map +1 -0
- package/build/services/StreamLifecycleController.js +152 -0
- package/build/services/StreamLifecycleController.js.map +1 -0
- package/build/services/TTSModelManager.d.ts +90 -0
- package/build/services/TTSModelManager.d.ts.map +1 -0
- package/build/services/TTSModelManager.js +366 -0
- package/build/services/TTSModelManager.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/WebviewBridge.d.ts +22 -0
- package/build/services/WebviewBridge.d.ts.map +1 -0
- package/build/services/WebviewBridge.js +47 -0
- package/build/services/WebviewBridge.js.map +1 -0
- package/build/services/asg/GalleryMediaIntegrityReportService.d.ts +17 -0
- package/build/services/asg/GalleryMediaIntegrityReportService.d.ts.map +1 -0
- package/build/services/asg/GalleryMediaIntegrityReportService.js +43 -0
- package/build/services/asg/GalleryMediaIntegrityReportService.js.map +1 -0
- package/build/services/asg/asgCameraApi.d.ts +205 -0
- package/build/services/asg/asgCameraApi.d.ts.map +1 -0
- package/build/services/asg/asgCameraApi.js +1410 -0
- package/build/services/asg/asgCameraApi.js.map +1 -0
- 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/galleryMediaValidation.d.ts +29 -0
- package/build/services/asg/galleryMediaValidation.d.ts.map +1 -0
- package/build/services/asg/galleryMediaValidation.js +149 -0
- package/build/services/asg/galleryMediaValidation.js.map +1 -0
- package/build/services/asg/galleryNotices.d.ts +33 -0
- package/build/services/asg/galleryNotices.d.ts.map +1 -0
- package/build/services/asg/galleryNotices.js +29 -0
- package/build/services/asg/galleryNotices.js.map +1 -0
- 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 +20 -0
- package/build/services/asg/gallerySettingsService.d.ts.map +1 -0
- package/build/services/asg/gallerySettingsService.js +53 -0
- package/build/services/asg/gallerySettingsService.js.map +1 -0
- package/build/services/asg/gallerySyncNotifications.d.ts +56 -0
- package/build/services/asg/gallerySyncNotifications.d.ts.map +1 -0
- package/build/services/asg/gallerySyncNotifications.js +198 -0
- package/build/services/asg/gallerySyncNotifications.js.map +1 -0
- package/build/services/asg/gallerySyncService.d.ts +137 -0
- package/build/services/asg/gallerySyncService.d.ts.map +1 -0
- package/build/services/asg/gallerySyncService.js +1933 -0
- package/build/services/asg/gallerySyncService.js.map +1 -0
- 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 +146 -0
- package/build/services/asg/localStorageService.d.ts.map +1 -0
- package/build/services/asg/localStorageService.js +572 -0
- package/build/services/asg/localStorageService.js.map +1 -0
- package/build/services/asg/mediaProcessingQueue.d.ts +70 -0
- package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -0
- package/build/services/asg/mediaProcessingQueue.js +451 -0
- package/build/services/asg/mediaProcessingQueue.js.map +1 -0
- package/build/services/asgOtaVersionUrl.d.ts +2 -0
- package/build/services/asgOtaVersionUrl.d.ts.map +1 -0
- package/build/services/asgOtaVersionUrl.js +36 -0
- package/build/services/asgOtaVersionUrl.js.map +1 -0
- package/build/services/blobPaths.d.ts +31 -0
- package/build/services/blobPaths.d.ts.map +1 -0
- package/build/services/blobPaths.js +86 -0
- package/build/services/blobPaths.js.map +1 -0
- package/build/services/cloudStreamApi.d.ts +59 -0
- package/build/services/cloudStreamApi.d.ts.map +1 -0
- package/build/services/cloudStreamApi.js +81 -0
- package/build/services/cloudStreamApi.js.map +1 -0
- package/build/services/gallerySyncClock.d.ts +17 -0
- package/build/services/gallerySyncClock.d.ts.map +1 -0
- package/build/services/gallerySyncClock.js +21 -0
- package/build/services/gallerySyncClock.js.map +1 -0
- package/build/services/glassesClockSync.d.ts +20 -0
- package/build/services/glassesClockSync.d.ts.map +1 -0
- package/build/services/glassesClockSync.js +97 -0
- package/build/services/glassesClockSync.js.map +1 -0
- package/build/services/manifestVersionGate.d.ts +28 -0
- package/build/services/manifestVersionGate.d.ts.map +1 -0
- package/build/services/manifestVersionGate.js +41 -0
- package/build/services/manifestVersionGate.js.map +1 -0
- package/build/services/mentraUiShim.d.ts +38 -0
- package/build/services/mentraUiShim.d.ts.map +1 -0
- package/build/services/mentraUiShim.js +360 -0
- package/build/services/mentraUiShim.js.map +1 -0
- package/build/services/navigation/roadNameResolver.d.ts +67 -0
- package/build/services/navigation/roadNameResolver.d.ts.map +1 -0
- package/build/services/navigation/roadNameResolver.js +96 -0
- package/build/services/navigation/roadNameResolver.js.map +1 -0
- package/build/services/navigation/routesApiCodec.d.ts +38 -0
- package/build/services/navigation/routesApiCodec.d.ts.map +1 -0
- package/build/services/navigation/routesApiCodec.js +68 -0
- package/build/services/navigation/routesApiCodec.js.map +1 -0
- package/build/services/otaDisplayState.d.ts +42 -0
- package/build/services/otaDisplayState.d.ts.map +1 -0
- package/build/services/otaDisplayState.js +92 -0
- package/build/services/otaDisplayState.js.map +1 -0
- package/build/services/otaInstallPolicy.d.ts +81 -0
- package/build/services/otaInstallPolicy.d.ts.map +1 -0
- package/build/services/otaInstallPolicy.js +96 -0
- package/build/services/otaInstallPolicy.js.map +1 -0
- package/build/services/otaLegacyMapping.d.ts +22 -0
- package/build/services/otaLegacyMapping.d.ts.map +1 -0
- package/build/services/otaLegacyMapping.js +56 -0
- package/build/services/otaLegacyMapping.js.map +1 -0
- package/build/services/slimStreamStatus.d.ts +7 -0
- package/build/services/slimStreamStatus.d.ts.map +1 -0
- package/build/services/slimStreamStatus.js +26 -0
- package/build/services/slimStreamStatus.js.map +1 -0
- package/build/stores/apps.d.ts +104 -0
- package/build/stores/apps.d.ts.map +1 -0
- package/build/stores/apps.js +492 -0
- package/build/stores/apps.js.map +1 -0
- package/build/stores/bluetoothSettingKeys.d.ts +4 -0
- package/build/stores/bluetoothSettingKeys.d.ts.map +1 -0
- package/build/stores/bluetoothSettingKeys.js +31 -0
- package/build/stores/bluetoothSettingKeys.js.map +1 -0
- package/build/stores/cloudClientStatus.d.ts +9 -0
- package/build/stores/cloudClientStatus.d.ts.map +1 -0
- package/build/stores/cloudClientStatus.js +24 -0
- package/build/stores/cloudClientStatus.js.map +1 -0
- package/build/stores/connection.d.ts +22 -0
- package/build/stores/connection.d.ts.map +1 -0
- package/build/stores/connection.js +43 -0
- package/build/stores/connection.js.map +1 -0
- package/build/stores/core.d.ts +15 -0
- package/build/stores/core.d.ts.map +1 -0
- package/build/stores/core.js +21 -0
- package/build/stores/core.js.map +1 -0
- package/build/stores/display.d.ts +24 -0
- package/build/stores/display.d.ts.map +1 -0
- package/build/stores/display.js +96 -0
- package/build/stores/display.js.map +1 -0
- package/build/stores/gallerySync.d.ts +101 -0
- package/build/stores/gallerySync.d.ts.map +1 -0
- package/build/stores/gallerySync.js +217 -0
- package/build/stores/gallerySync.js.map +1 -0
- package/build/stores/glasses.d.ts +62 -0
- package/build/stores/glasses.d.ts.map +1 -0
- package/build/stores/glasses.js +203 -0
- package/build/stores/glasses.js.map +1 -0
- package/build/stores/settings.d.ts +37 -0
- package/build/stores/settings.d.ts.map +1 -0
- package/build/stores/settings.js +922 -0
- package/build/stores/settings.js.map +1 -0
- package/build/types/applet.d.ts +96 -0
- package/build/types/applet.d.ts.map +1 -0
- package/build/types/applet.js +5 -0
- package/build/types/applet.js.map +1 -0
- package/build/types/asg.d.ts +53 -0
- package/build/types/asg.d.ts.map +1 -0
- package/build/types/asg.js +2 -0
- package/build/types/asg.js.map +1 -0
- package/build/types/capabilities/even-realities-g1.d.ts +12 -0
- package/build/types/capabilities/even-realities-g1.d.ts.map +1 -0
- package/build/types/capabilities/even-realities-g1.js +55 -0
- package/build/types/capabilities/even-realities-g1.js.map +1 -0
- package/build/types/capabilities/even-realities-g2.d.ts +12 -0
- package/build/types/capabilities/even-realities-g2.d.ts.map +1 -0
- package/build/types/capabilities/even-realities-g2.js +75 -0
- package/build/types/capabilities/even-realities-g2.js.map +1 -0
- package/build/types/capabilities/mentra-display.d.ts +12 -0
- package/build/types/capabilities/mentra-display.d.ts.map +1 -0
- package/build/types/capabilities/mentra-display.js +63 -0
- package/build/types/capabilities/mentra-display.js.map +1 -0
- package/build/types/capabilities/mentra-live.d.ts +12 -0
- package/build/types/capabilities/mentra-live.d.ts.map +1 -0
- package/build/types/capabilities/mentra-live.js +92 -0
- package/build/types/capabilities/mentra-live.js.map +1 -0
- package/build/types/capabilities/none.d.ts +13 -0
- package/build/types/capabilities/none.d.ts.map +1 -0
- package/build/types/capabilities/none.js +65 -0
- package/build/types/capabilities/none.js.map +1 -0
- package/build/types/capabilities/simulated-glasses.d.ts +13 -0
- package/build/types/capabilities/simulated-glasses.d.ts.map +1 -0
- package/build/types/capabilities/simulated-glasses.js +65 -0
- package/build/types/capabilities/simulated-glasses.js.map +1 -0
- package/build/types/capabilities/vuzix-z100.d.ts +12 -0
- package/build/types/capabilities/vuzix-z100.d.ts.map +1 -0
- package/build/types/capabilities/vuzix-z100.js +52 -0
- package/build/types/capabilities/vuzix-z100.js.map +1 -0
- package/build/types/enums.d.ts +40 -0
- package/build/types/enums.d.ts.map +1 -0
- package/build/types/enums.js +44 -0
- package/build/types/enums.js.map +1 -0
- package/build/types/hardware.d.ts +160 -0
- package/build/types/hardware.d.ts.map +1 -0
- package/build/types/hardware.js +36 -0
- package/build/types/hardware.js.map +1 -0
- package/build/types/index.d.ts +11 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/index.js +10 -0
- package/build/types/index.js.map +1 -0
- package/build/utils/GlobalEventEmitter.d.ts +10 -0
- package/build/utils/GlobalEventEmitter.d.ts.map +1 -0
- package/build/utils/GlobalEventEmitter.js +13 -0
- package/build/utils/GlobalEventEmitter.js.map +1 -0
- package/build/utils/cloudClient/RnUdpAdapter.d.ts +3 -0
- package/build/utils/cloudClient/RnUdpAdapter.d.ts.map +1 -0
- package/build/utils/cloudClient/RnUdpAdapter.js +41 -0
- package/build/utils/cloudClient/RnUdpAdapter.js.map +1 -0
- package/build/utils/cloudClient/cloudSecureStore.d.ts +3 -0
- package/build/utils/cloudClient/cloudSecureStore.d.ts.map +1 -0
- package/build/utils/cloudClient/cloudSecureStore.js +26 -0
- package/build/utils/cloudClient/cloudSecureStore.js.map +1 -0
- package/build/utils/debouncedPatch.d.ts +6 -0
- package/build/utils/debouncedPatch.d.ts.map +1 -0
- package/build/utils/debouncedPatch.js +25 -0
- package/build/utils/debouncedPatch.js.map +1 -0
- package/build/utils/devLogging.d.ts +26 -0
- package/build/utils/devLogging.d.ts.map +1 -0
- package/build/utils/devLogging.js +116 -0
- package/build/utils/devLogging.js.map +1 -0
- package/build/utils/devMiniappLaunch.d.ts +44 -0
- package/build/utils/devMiniappLaunch.d.ts.map +1 -0
- package/build/utils/devMiniappLaunch.js +52 -0
- package/build/utils/devMiniappLaunch.js.map +1 -0
- package/build/utils/diagnosticContext.d.ts +3 -0
- package/build/utils/diagnosticContext.d.ts.map +1 -0
- package/build/utils/diagnosticContext.js +119 -0
- package/build/utils/diagnosticContext.js.map +1 -0
- package/build/utils/display/composer/ColumnComposer.d.ts +131 -0
- package/build/utils/display/composer/ColumnComposer.d.ts.map +1 -0
- package/build/utils/display/composer/ColumnComposer.js +204 -0
- package/build/utils/display/composer/ColumnComposer.js.map +1 -0
- package/build/utils/display/composer/index.d.ts +9 -0
- package/build/utils/display/composer/index.d.ts.map +1 -0
- package/build/utils/display/composer/index.js +9 -0
- package/build/utils/display/composer/index.js.map +1 -0
- package/build/utils/display/helpers/DisplayHelpers.d.ts +165 -0
- package/build/utils/display/helpers/DisplayHelpers.d.ts.map +1 -0
- package/build/utils/display/helpers/DisplayHelpers.js +312 -0
- package/build/utils/display/helpers/DisplayHelpers.js.map +1 -0
- package/build/utils/display/helpers/ScrollView.d.ts +183 -0
- package/build/utils/display/helpers/ScrollView.d.ts.map +1 -0
- package/build/utils/display/helpers/ScrollView.js +257 -0
- package/build/utils/display/helpers/ScrollView.js.map +1 -0
- package/build/utils/display/helpers/index.d.ts +11 -0
- package/build/utils/display/helpers/index.d.ts.map +1 -0
- package/build/utils/display/helpers/index.js +10 -0
- package/build/utils/display/helpers/index.js.map +1 -0
- package/build/utils/display/index.d.ts +174 -0
- package/build/utils/display/index.d.ts.map +1 -0
- package/build/utils/display/index.js +185 -0
- package/build/utils/display/index.js.map +1 -0
- package/build/utils/display/measurer/TextMeasurer.d.ts +160 -0
- package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -0
- package/build/utils/display/measurer/TextMeasurer.js +273 -0
- package/build/utils/display/measurer/TextMeasurer.js.map +1 -0
- package/build/utils/display/measurer/index.d.ts +10 -0
- package/build/utils/display/measurer/index.d.ts.map +1 -0
- package/build/utils/display/measurer/index.js +11 -0
- package/build/utils/display/measurer/index.js.map +1 -0
- package/build/utils/display/measurer/script-detection.d.ts +53 -0
- package/build/utils/display/measurer/script-detection.d.ts.map +1 -0
- package/build/utils/display/measurer/script-detection.js +184 -0
- package/build/utils/display/measurer/script-detection.js.map +1 -0
- package/build/utils/display/profiles/g1.d.ts +33 -0
- package/build/utils/display/profiles/g1.d.ts.map +1 -0
- package/build/utils/display/profiles/g1.js +213 -0
- package/build/utils/display/profiles/g1.js.map +1 -0
- package/build/utils/display/profiles/g2.d.ts +13 -0
- package/build/utils/display/profiles/g2.d.ts.map +1 -0
- package/build/utils/display/profiles/g2.js +34 -0
- package/build/utils/display/profiles/g2.js.map +1 -0
- package/build/utils/display/profiles/index.d.ts +12 -0
- package/build/utils/display/profiles/index.d.ts.map +1 -0
- package/build/utils/display/profiles/index.js +15 -0
- package/build/utils/display/profiles/index.js.map +1 -0
- package/build/utils/display/profiles/nex.d.ts +10 -0
- package/build/utils/display/profiles/nex.d.ts.map +1 -0
- package/build/utils/display/profiles/nex.js +150 -0
- package/build/utils/display/profiles/nex.js.map +1 -0
- package/build/utils/display/profiles/types.d.ts +103 -0
- package/build/utils/display/profiles/types.d.ts.map +1 -0
- package/build/utils/display/profiles/types.js +2 -0
- package/build/utils/display/profiles/types.js.map +1 -0
- package/build/utils/display/profiles/z100.d.ts +33 -0
- package/build/utils/display/profiles/z100.d.ts.map +1 -0
- package/build/utils/display/profiles/z100.js +182 -0
- package/build/utils/display/profiles/z100.js.map +1 -0
- package/build/utils/display/scene/degrade.d.ts +25 -0
- package/build/utils/display/scene/degrade.d.ts.map +1 -0
- package/build/utils/display/scene/degrade.js +64 -0
- package/build/utils/display/scene/degrade.js.map +1 -0
- package/build/utils/display/scene/differ.d.ts +38 -0
- package/build/utils/display/scene/differ.d.ts.map +1 -0
- package/build/utils/display/scene/differ.js +107 -0
- package/build/utils/display/scene/differ.js.map +1 -0
- package/build/utils/display/scene/index.d.ts +10 -0
- package/build/utils/display/scene/index.d.ts.map +1 -0
- package/build/utils/display/scene/index.js +6 -0
- package/build/utils/display/scene/index.js.map +1 -0
- package/build/utils/display/scene/process.d.ts +35 -0
- package/build/utils/display/scene/process.d.ts.map +1 -0
- package/build/utils/display/scene/process.js +187 -0
- package/build/utils/display/scene/process.js.map +1 -0
- package/build/utils/display/scene/store.d.ts +48 -0
- package/build/utils/display/scene/store.d.ts.map +1 -0
- package/build/utils/display/scene/store.js +0 -0
- package/build/utils/display/scene/store.js.map +1 -0
- package/build/utils/display/scene/types.d.ts +120 -0
- package/build/utils/display/scene/types.d.ts.map +1 -0
- package/build/utils/display/scene/types.js +0 -0
- package/build/utils/display/scene/types.js.map +1 -0
- package/build/utils/display/wrapper/TextWrapper.d.ts +102 -0
- package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -0
- package/build/utils/display/wrapper/TextWrapper.js +471 -0
- package/build/utils/display/wrapper/TextWrapper.js.map +1 -0
- package/build/utils/display/wrapper/index.d.ts +12 -0
- package/build/utils/display/wrapper/index.d.ts.map +1 -0
- package/build/utils/display/wrapper/index.js +12 -0
- package/build/utils/display/wrapper/index.js.map +1 -0
- package/build/utils/display/wrapper/types.d.ts +75 -0
- package/build/utils/display/wrapper/types.d.ts.map +1 -0
- package/build/utils/display/wrapper/types.js +11 -0
- package/build/utils/display/wrapper/types.js.map +1 -0
- package/build/utils/e2eMetrics.d.ts +6 -0
- package/build/utils/e2eMetrics.d.ts.map +1 -0
- package/build/utils/e2eMetrics.js +27 -0
- package/build/utils/e2eMetrics.js.map +1 -0
- package/build/utils/hardware/hardware.d.ts +42 -0
- package/build/utils/hardware/hardware.d.ts.map +1 -0
- package/build/utils/hardware/hardware.js +127 -0
- package/build/utils/hardware/hardware.js.map +1 -0
- package/build/utils/hardware/index.d.ts +2 -0
- package/build/utils/hardware/index.d.ts.map +1 -0
- package/build/utils/hardware/index.js +2 -0
- package/build/utils/hardware/index.js.map +1 -0
- package/build/utils/miniappGlobals.d.ts +60 -0
- package/build/utils/miniappGlobals.d.ts.map +1 -0
- package/build/utils/miniappGlobals.js +224 -0
- package/build/utils/miniappGlobals.js.map +1 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts +45 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -0
- package/build/utils/permissions/MediaLibraryPermissions.js +145 -0
- package/build/utils/permissions/MediaLibraryPermissions.js.map +1 -0
- package/build/utils/permissions/galleryDisplayName.d.ts +8 -0
- package/build/utils/permissions/galleryDisplayName.d.ts.map +1 -0
- package/build/utils/permissions/galleryDisplayName.js +25 -0
- package/build/utils/permissions/galleryDisplayName.js.map +1 -0
- package/build/utils/storage/index.d.ts +3 -0
- package/build/utils/storage/index.d.ts.map +1 -0
- package/build/utils/storage/index.js +3 -0
- package/build/utils/storage/index.js.map +1 -0
- package/build/utils/storage/storage.d.ts +24 -0
- package/build/utils/storage/storage.d.ts.map +1 -0
- package/build/utils/storage/storage.js +85 -0
- package/build/utils/storage/storage.js.map +1 -0
- package/build/utils/storage/zip.d.ts +3 -0
- package/build/utils/storage/zip.d.ts.map +1 -0
- package/build/utils/storage/zip.js +14 -0
- package/build/utils/storage/zip.js.map +1 -0
- package/build/utils/timers/index.d.ts +3 -0
- package/build/utils/timers/index.d.ts.map +1 -0
- package/build/utils/timers/index.js +3 -0
- package/build/utils/timers/index.js.map +1 -0
- package/build/utils/timers/timers.d.ts +9 -0
- package/build/utils/timers/timers.d.ts.map +1 -0
- package/build/utils/timers/timers.js +105 -0
- package/build/utils/timers/timers.js.map +1 -0
- package/package.json +120 -0
- package/src/devtools.ts +13 -0
- package/src/engine.ts +173 -0
- package/src/facades/dev.ts +198 -0
- package/src/facades/display.ts +17 -0
- package/src/facades/displayMirror.ts +33 -0
- package/src/facades/gallery.ts +69 -0
- package/src/facades/glasses.ts +206 -0
- package/src/facades/glassesSettings.ts +56 -0
- package/src/facades/glassesWifi.ts +68 -0
- package/src/facades/miniapps.ts +55 -0
- package/src/facades/notifications.ts +15 -0
- package/src/facades/ota.ts +174 -0
- package/src/facades/pairing.ts +329 -0
- package/src/facades/permissions.ts +165 -0
- package/src/facades/phoneNotifications.ts +50 -0
- package/src/facades/reports.ts +185 -0
- package/src/facades/session.ts +55 -0
- package/src/facades/settings.ts +57 -0
- package/src/facades/speech.ts +38 -0
- package/src/index.ts +191 -0
- package/src/internal.ts +159 -0
- package/src/runtime/bootstrap.ts +118 -0
- package/src/runtime/config.ts +147 -0
- package/src/runtime/streamConfig.ts +34 -0
- package/src/services/AppRegistry.ts +1190 -0
- package/src/services/AudioCloudUplink.ts +50 -0
- package/src/services/AudioPlaybackService.ts +813 -0
- package/src/services/AutomaticReportResult.ts +48 -0
- package/src/services/BlobStore.ts +746 -0
- package/src/services/CaptionsTesterReportService.ts +107 -0
- package/src/services/CloudAudioSubscriptionSync.ts +41 -0
- package/src/services/CloudClientService.ts +689 -0
- package/src/services/CloudTranscriptE2EMetrics.ts +27 -0
- package/src/services/ConnectionCoordinator.ts +65 -0
- package/src/services/DevServerBridge.ts +332 -0
- package/src/services/DeviceEventRouter.ts +238 -0
- package/src/services/DeviceStoreHydration.ts +130 -0
- package/src/services/DisplayProcessor.ts +775 -0
- package/src/services/GlassesReadiness.ts +103 -0
- package/src/services/GlassesSettingsSync.ts +134 -0
- package/src/services/GlassesStatusProjection.ts +73 -0
- package/src/services/HeadingService.ts +98 -0
- package/src/services/LocalDisplayManager.ts +703 -0
- package/src/services/LocalMiniappRuntime.ts +4213 -0
- package/src/services/LocalSttFallbackCoordinator.ts +147 -0
- package/src/services/MentraJSCrashController.ts +189 -0
- package/src/services/MentraJSCrashloopReportService.ts +66 -0
- package/src/services/MentraJSLogPipeline.ts +166 -0
- package/src/services/MentraJSRouter.ts +557 -0
- package/src/services/MentraUIRouter.ts +244 -0
- package/src/services/MicStateCoordinator.ts +94 -0
- package/src/services/MiniappEngine.ts +143 -0
- package/src/services/MiniappLauncher.ts +340 -0
- package/src/services/MiniappRunningRegistry.ts +57 -0
- package/src/services/NativeHttpResponse.ts +6 -0
- package/src/services/NavigationHandlers.ts +423 -0
- package/src/services/NavigationService.ts +731 -0
- package/src/services/NotificationsEmitter.ts +48 -0
- package/src/services/OfflineSpeechModelService.ts +168 -0
- package/src/services/OtaInstallCoordinator.ts +1205 -0
- package/src/services/OtaService.ts +83 -0
- package/src/services/OtaUpdateCheckService.ts +386 -0
- package/src/services/PairingIdentity.ts +154 -0
- package/src/services/PhoneCalendarHelpers.ts +212 -0
- package/src/services/PhoneCalendarService.ts +42 -0
- package/src/services/PhoneCameraFovCoordinator.ts +195 -0
- package/src/services/PhoneLocationService.ts +122 -0
- package/src/services/PhoneNotificationsSync.ts +44 -0
- package/src/services/PhonePhotoCoordinator.ts +409 -0
- package/src/services/PhoneStreamCoordinator.ts +777 -0
- package/src/services/PhoneVideoCoordinator.ts +189 -0
- package/src/services/STTModelManager.ts +360 -0
- package/src/services/SceneRenderer.ts +292 -0
- package/src/services/SentenceTtsPipeline.ts +106 -0
- package/src/services/StreamLifecycleController.ts +213 -0
- package/src/services/TTSModelManager.ts +466 -0
- package/src/services/TranscriptionRouting.ts +37 -0
- package/src/services/WebviewBridge.ts +50 -0
- package/src/services/asg/GalleryMediaIntegrityReportService.ts +70 -0
- package/src/services/asg/asgCameraApi.ts +1695 -0
- package/src/services/asg/cameraRollExportCoordinator.ts +627 -0
- package/src/services/asg/cameraRollExportLedger.ts +122 -0
- package/src/services/asg/galleryMediaValidation.ts +183 -0
- package/src/services/asg/galleryNotices.ts +61 -0
- package/src/services/asg/galleryPathMigration.ts +22 -0
- package/src/services/asg/gallerySettingsService.ts +68 -0
- package/src/services/asg/gallerySyncNotifications.ts +236 -0
- package/src/services/asg/gallerySyncService.ts +2269 -0
- package/src/services/asg/galleryTransferLedger.ts +312 -0
- package/src/services/asg/localNetworkTransport.ts +173 -0
- package/src/services/asg/localStorageService.ts +652 -0
- package/src/services/asg/mediaProcessingQueue.ts +518 -0
- package/src/services/asgOtaVersionUrl.ts +41 -0
- package/src/services/blobPaths.ts +86 -0
- package/src/services/cloudStreamApi.ts +154 -0
- package/src/services/gallerySyncClock.ts +39 -0
- package/src/services/glassesClockSync.ts +115 -0
- package/src/services/manifestVersionGate.ts +43 -0
- package/src/services/mentraUiShim.ts +366 -0
- package/src/services/navigation/roadNameResolver.ts +112 -0
- package/src/services/navigation/routesApiCodec.ts +69 -0
- package/src/services/otaDisplayState.ts +115 -0
- package/src/services/otaInstallPolicy.ts +106 -0
- package/src/services/otaLegacyMapping.ts +71 -0
- package/src/services/slimStreamStatus.ts +28 -0
- package/src/stores/apps.ts +614 -0
- package/src/stores/bluetoothSettingKeys.ts +36 -0
- package/src/stores/cloudClientStatus.ts +37 -0
- package/src/stores/connection.ts +69 -0
- package/src/stores/core.ts +32 -0
- package/src/stores/display.ts +121 -0
- package/src/stores/gallerySync.ts +380 -0
- package/src/stores/glasses.ts +309 -0
- package/src/stores/settings.ts +1001 -0
- package/src/types/applet.ts +112 -0
- package/src/types/asg.ts +58 -0
- package/src/types/capabilities/even-realities-g1.ts +67 -0
- package/src/types/capabilities/even-realities-g2.ts +88 -0
- package/src/types/capabilities/mentra-display.ts +75 -0
- package/src/types/capabilities/mentra-live.ts +103 -0
- package/src/types/capabilities/none.ts +76 -0
- package/src/types/capabilities/simulated-glasses.ts +76 -0
- package/src/types/capabilities/vuzix-z100.ts +64 -0
- package/src/types/enums.ts +43 -0
- package/src/types/hardware.ts +203 -0
- package/src/types/index.ts +37 -0
- package/src/utils/GlobalEventEmitter.ts +14 -0
- package/src/utils/cloudClient/RnUdpAdapter.ts +47 -0
- package/src/utils/cloudClient/cloudSecureStore.ts +28 -0
- package/src/utils/debouncedPatch.ts +28 -0
- package/src/utils/devLogging.ts +140 -0
- package/src/utils/devMiniappLaunch.ts +68 -0
- package/src/utils/diagnosticContext.ts +155 -0
- package/src/utils/display/composer/ColumnComposer.ts +285 -0
- package/src/utils/display/composer/index.ts +15 -0
- package/src/utils/display/helpers/DisplayHelpers.ts +413 -0
- package/src/utils/display/helpers/ScrollView.ts +337 -0
- package/src/utils/display/helpers/index.ts +14 -0
- package/src/utils/display/index.ts +273 -0
- package/src/utils/display/measurer/TextMeasurer.ts +346 -0
- package/src/utils/display/measurer/index.ts +21 -0
- package/src/utils/display/measurer/script-detection.ts +218 -0
- package/src/utils/display/profiles/g1.ts +236 -0
- package/src/utils/display/profiles/g2.ts +39 -0
- package/src/utils/display/profiles/index.ts +28 -0
- package/src/utils/display/profiles/nex.ts +166 -0
- package/src/utils/display/profiles/types.ts +132 -0
- package/src/utils/display/profiles/z100.ts +198 -0
- package/src/utils/display/scene/degrade.ts +80 -0
- package/src/utils/display/scene/differ.ts +128 -0
- package/src/utils/display/scene/index.ts +21 -0
- package/src/utils/display/scene/process.ts +214 -0
- package/src/utils/display/scene/store.ts +0 -0
- package/src/utils/display/scene/types.ts +0 -0
- package/src/utils/display/wrapper/TextWrapper.ts +546 -0
- package/src/utils/display/wrapper/index.ts +15 -0
- package/src/utils/display/wrapper/types.ts +102 -0
- package/src/utils/e2eMetrics.ts +30 -0
- package/src/utils/hardware/hardware.ts +166 -0
- package/src/utils/hardware/index.ts +1 -0
- package/src/utils/miniappGlobals.ts +260 -0
- package/src/utils/permissions/MediaLibraryPermissions.ts +161 -0
- package/src/utils/permissions/galleryDisplayName.ts +28 -0
- package/src/utils/storage/index.ts +2 -0
- package/src/utils/storage/storage.ts +101 -0
- package/src/utils/storage/zip.ts +13 -0
- package/src/utils/timers/index.ts +2 -0
- package/src/utils/timers/timers.ts +139 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SETTINGS, useSettingsStore } from "../stores/settings";
|
|
2
|
+
const OTA_VERSION_URL_PROD = "https://ota.mentraglass.com/prod_live_version.json";
|
|
3
|
+
function isLegacyAsgOtaStartBuild(glassesBuildNumber) {
|
|
4
|
+
const buildNumber = Number.parseInt(glassesBuildNumber ?? "", 10);
|
|
5
|
+
// ASG builds before 39 ignore ota_start.ota_version_url, so compare against
|
|
6
|
+
// the URL they will actually use.
|
|
7
|
+
return Number.isFinite(buildNumber) && buildNumber < 39;
|
|
8
|
+
}
|
|
9
|
+
function getOtaVersionUrlDevOverride() {
|
|
10
|
+
// Super mode only: a wrong OTA manifest can brick glasses, so a saved
|
|
11
|
+
// override is inert unless super mode is currently enabled.
|
|
12
|
+
if (!useSettingsStore.getState().getSetting(SETTINGS.super_mode.key)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const value = useSettingsStore.getState().getSetting(SETTINGS.ota_version_url.key);
|
|
16
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
17
|
+
return trimmed || null;
|
|
18
|
+
}
|
|
19
|
+
export function getAsgOtaVersionUrl(glassesUrl, glassesBuildNumber) {
|
|
20
|
+
const deviceUrl = glassesUrl?.trim();
|
|
21
|
+
if (isLegacyAsgOtaStartBuild(glassesBuildNumber)) {
|
|
22
|
+
// Legacy glasses ignore ota_start.ota_version_url and install from their
|
|
23
|
+
// compiled default, so the developer override does not apply to them either.
|
|
24
|
+
return deviceUrl || OTA_VERSION_URL_PROD;
|
|
25
|
+
}
|
|
26
|
+
const devOverrideUrl = getOtaVersionUrlDevOverride();
|
|
27
|
+
if (devOverrideUrl) {
|
|
28
|
+
return devOverrideUrl;
|
|
29
|
+
}
|
|
30
|
+
const envUrl = process.env.EXPO_PUBLIC_ASG_OTA_VERSION_URL?.trim();
|
|
31
|
+
if (envUrl) {
|
|
32
|
+
return envUrl;
|
|
33
|
+
}
|
|
34
|
+
return deviceUrl || OTA_VERSION_URL_PROD;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=asgOtaVersionUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asgOtaVersionUrl.js","sourceRoot":"","sources":["../../src/services/asgOtaVersionUrl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAE7D,MAAM,oBAAoB,GAAG,oDAAoD,CAAA;AAEjF,SAAS,wBAAwB,CAAC,kBAAkC;IAClE,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,kBAAkB,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACjE,4EAA4E;IAC5E,kCAAkC;IAClC,OAAO,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,EAAE,CAAA;AACzD,CAAC;AAED,SAAS,2BAA2B;IAClC,sEAAsE;IACtE,4DAA4D;IAC5D,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrE,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,CAAA;IAClF,MAAM,OAAO,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7D,OAAO,OAAO,IAAI,IAAI,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAA0B,EAAE,kBAAkC;IAChG,MAAM,SAAS,GAAG,UAAU,EAAE,IAAI,EAAE,CAAA;IACpC,IAAI,wBAAwB,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACjD,yEAAyE;QACzE,6EAA6E;QAC7E,OAAO,SAAS,IAAI,oBAAoB,CAAA;IAC1C,CAAC;IAED,MAAM,cAAc,GAAG,2BAA2B,EAAE,CAAA;IACpD,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,IAAI,EAAE,CAAA;IAClE,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAA;IACf,CAAC;IACD,OAAO,SAAS,IAAI,oBAAoB,CAAA;AAC1C,CAAC","sourcesContent":["import {SETTINGS, useSettingsStore} from \"../stores/settings\"\n\nconst OTA_VERSION_URL_PROD = \"https://ota.mentraglass.com/prod_live_version.json\"\n\nfunction isLegacyAsgOtaStartBuild(glassesBuildNumber?: string | null): boolean {\n const buildNumber = Number.parseInt(glassesBuildNumber ?? \"\", 10)\n // ASG builds before 39 ignore ota_start.ota_version_url, so compare against\n // the URL they will actually use.\n return Number.isFinite(buildNumber) && buildNumber < 39\n}\n\nfunction getOtaVersionUrlDevOverride(): string | null {\n // Super mode only: a wrong OTA manifest can brick glasses, so a saved\n // override is inert unless super mode is currently enabled.\n if (!useSettingsStore.getState().getSetting(SETTINGS.super_mode.key)) {\n return null\n }\n const value = useSettingsStore.getState().getSetting(SETTINGS.ota_version_url.key)\n const trimmed = typeof value === \"string\" ? value.trim() : \"\"\n return trimmed || null\n}\n\nexport function getAsgOtaVersionUrl(glassesUrl?: string | null, glassesBuildNumber?: string | null): string {\n const deviceUrl = glassesUrl?.trim()\n if (isLegacyAsgOtaStartBuild(glassesBuildNumber)) {\n // Legacy glasses ignore ota_start.ota_version_url and install from their\n // compiled default, so the developer override does not apply to them either.\n return deviceUrl || OTA_VERSION_URL_PROD\n }\n\n const devOverrideUrl = getOtaVersionUrlDevOverride()\n if (devOverrideUrl) {\n return devOverrideUrl\n }\n\n const envUrl = process.env.EXPO_PUBLIC_ASG_OTA_VERSION_URL?.trim()\n if (envUrl) {\n return envUrl\n }\n return deviceUrl || OTA_VERSION_URL_PROD\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure path helper for BlobStore. No React Native / Expo imports, so it's
|
|
3
|
+
* unit-testable in isolation (see blobPaths.test.ts).
|
|
4
|
+
*/
|
|
5
|
+
/** Filesystem-safe path segment. Strips traversal + unsafe chars; never empty. */
|
|
6
|
+
export declare function sanitizeSegment(s: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Filesystem-safe display name for a shared blob, guaranteed to carry an
|
|
9
|
+
* extension. The on-disk blob name is a generated machine id (with a
|
|
10
|
+
* mime-derived extension since withDiskExt; legacy blobs may lack it), so the
|
|
11
|
+
* OS share sheet (which keys off the file path, not any metadata) would
|
|
12
|
+
* otherwise emit a machine-named file — breaking "open with"/preview on the
|
|
13
|
+
* receiving side. Derives the extension from the mimeType when the stored name
|
|
14
|
+
* lacks one.
|
|
15
|
+
*/
|
|
16
|
+
export declare function shareFileName(meta: {
|
|
17
|
+
name?: string;
|
|
18
|
+
fileName: string;
|
|
19
|
+
mimeType: string;
|
|
20
|
+
}): string;
|
|
21
|
+
/**
|
|
22
|
+
* On-disk name for a stored blob: the generated id plus a mime-derived
|
|
23
|
+
* extension when one is known. iOS AVPlayer resolves a local file's format
|
|
24
|
+
* from its path extension (not content sniffing), so an extension-less WAV is
|
|
25
|
+
* unplayable through `session.speaker.play` even though the bytes are valid.
|
|
26
|
+
* Leaves a name that already has an extension untouched.
|
|
27
|
+
*/
|
|
28
|
+
export declare function withDiskExt(fileName: string, mimeType: string): string;
|
|
29
|
+
/** Best-effort file extension (no dot) for a MIME type. Inverse of inferMime in BlobStore. */
|
|
30
|
+
export declare function extForMime(mime: string): string | undefined;
|
|
31
|
+
//# sourceMappingURL=blobPaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blobPaths.d.ts","sourceRoot":"","sources":["../../src/services/blobPaths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAC,GAAG,MAAM,CAsB/F;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItE;AAED,8FAA8F;AAC9F,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA0B3D"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure path helper for BlobStore. No React Native / Expo imports, so it's
|
|
3
|
+
* unit-testable in isolation (see blobPaths.test.ts).
|
|
4
|
+
*/
|
|
5
|
+
/** Filesystem-safe path segment. Strips traversal + unsafe chars; never empty. */
|
|
6
|
+
export function sanitizeSegment(s) {
|
|
7
|
+
const cleaned = (s || "").replace(/[^A-Za-z0-9._-]/g, "_");
|
|
8
|
+
if (cleaned === "" || cleaned === "." || cleaned === "..")
|
|
9
|
+
return "_";
|
|
10
|
+
return cleaned.slice(0, 120);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Filesystem-safe display name for a shared blob, guaranteed to carry an
|
|
14
|
+
* extension. The on-disk blob name is a generated machine id (with a
|
|
15
|
+
* mime-derived extension since withDiskExt; legacy blobs may lack it), so the
|
|
16
|
+
* OS share sheet (which keys off the file path, not any metadata) would
|
|
17
|
+
* otherwise emit a machine-named file — breaking "open with"/preview on the
|
|
18
|
+
* receiving side. Derives the extension from the mimeType when the stored name
|
|
19
|
+
* lacks one.
|
|
20
|
+
*/
|
|
21
|
+
export function shareFileName(meta) {
|
|
22
|
+
const raw = (meta.name || meta.fileName).trim();
|
|
23
|
+
// Replace path separators + characters illegal on common filesystems (keep
|
|
24
|
+
// spaces, hyphens, dots, etc. — they're valid and keep names readable).
|
|
25
|
+
// eslint-disable-next-line no-control-regex
|
|
26
|
+
let safe = raw.replace(/[/\\<>:"|?*\x00-\x1f]/g, "_").trim();
|
|
27
|
+
if (!safe)
|
|
28
|
+
safe = meta.fileName;
|
|
29
|
+
// Split base + extension: use an extension already on the name, else derive
|
|
30
|
+
// one from the mimeType.
|
|
31
|
+
const dot = safe.lastIndexOf(".");
|
|
32
|
+
const hasExt = dot > 0 && dot < safe.length - 1;
|
|
33
|
+
let base = hasExt ? safe.slice(0, dot) : safe;
|
|
34
|
+
const ext = hasExt ? safe.slice(dot + 1) : extForMime(meta.mimeType);
|
|
35
|
+
const suffix = ext ? `.${ext}` : "";
|
|
36
|
+
// Bound the total length: common filesystems reject names over ~255 bytes, so
|
|
37
|
+
// a huge app-provided name would make the share's file copy throw. Truncate
|
|
38
|
+
// the base while preserving the extension (mirrors sanitizeSegment's ceiling).
|
|
39
|
+
const MAX_LEN = 120;
|
|
40
|
+
if (base.length + suffix.length > MAX_LEN) {
|
|
41
|
+
base = base.slice(0, Math.max(1, MAX_LEN - suffix.length));
|
|
42
|
+
}
|
|
43
|
+
return base + suffix;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* On-disk name for a stored blob: the generated id plus a mime-derived
|
|
47
|
+
* extension when one is known. iOS AVPlayer resolves a local file's format
|
|
48
|
+
* from its path extension (not content sniffing), so an extension-less WAV is
|
|
49
|
+
* unplayable through `session.speaker.play` even though the bytes are valid.
|
|
50
|
+
* Leaves a name that already has an extension untouched.
|
|
51
|
+
*/
|
|
52
|
+
export function withDiskExt(fileName, mimeType) {
|
|
53
|
+
if (fileName.includes("."))
|
|
54
|
+
return fileName;
|
|
55
|
+
const ext = extForMime(mimeType);
|
|
56
|
+
return ext ? `${fileName}.${ext}` : fileName;
|
|
57
|
+
}
|
|
58
|
+
/** Best-effort file extension (no dot) for a MIME type. Inverse of inferMime in BlobStore. */
|
|
59
|
+
export function extForMime(mime) {
|
|
60
|
+
const m = (mime || "").split(";")[0].trim().toLowerCase();
|
|
61
|
+
const map = {
|
|
62
|
+
"application/pdf": "pdf",
|
|
63
|
+
"application/epub+zip": "epub",
|
|
64
|
+
"application/zip": "zip",
|
|
65
|
+
"application/json": "json",
|
|
66
|
+
"text/plain": "txt",
|
|
67
|
+
"text/csv": "csv",
|
|
68
|
+
"text/html": "html",
|
|
69
|
+
"video/mp4": "mp4",
|
|
70
|
+
"video/quicktime": "mov",
|
|
71
|
+
"video/webm": "webm",
|
|
72
|
+
"audio/mpeg": "mp3",
|
|
73
|
+
"audio/mp4": "m4a",
|
|
74
|
+
"audio/wav": "wav",
|
|
75
|
+
"audio/x-wav": "wav",
|
|
76
|
+
"audio/wave": "wav",
|
|
77
|
+
"audio/ogg": "ogg",
|
|
78
|
+
"image/png": "png",
|
|
79
|
+
"image/jpeg": "jpg",
|
|
80
|
+
"image/gif": "gif",
|
|
81
|
+
"image/webp": "webp",
|
|
82
|
+
"image/svg+xml": "svg",
|
|
83
|
+
};
|
|
84
|
+
return map[m];
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=blobPaths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blobPaths.js","sourceRoot":"","sources":["../../src/services/blobPaths.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure path helper for BlobStore. No React Native / Expo imports, so it's\n * unit-testable in isolation (see blobPaths.test.ts).\n */\n\n/** Filesystem-safe path segment. Strips traversal + unsafe chars; never empty. */\nexport function sanitizeSegment(s: string): string {\n const cleaned = (s || \"\").replace(/[^A-Za-z0-9._-]/g, \"_\")\n if (cleaned === \"\" || cleaned === \".\" || cleaned === \"..\") return \"_\"\n return cleaned.slice(0, 120)\n}\n\n/**\n * Filesystem-safe display name for a shared blob, guaranteed to carry an\n * extension. The on-disk blob name is a generated machine id (with a\n * mime-derived extension since withDiskExt; legacy blobs may lack it), so the\n * OS share sheet (which keys off the file path, not any metadata) would\n * otherwise emit a machine-named file — breaking \"open with\"/preview on the\n * receiving side. Derives the extension from the mimeType when the stored name\n * lacks one.\n */\nexport function shareFileName(meta: {name?: string; fileName: string; mimeType: string}): string {\n const raw = (meta.name || meta.fileName).trim()\n // Replace path separators + characters illegal on common filesystems (keep\n // spaces, hyphens, dots, etc. — they're valid and keep names readable).\n // eslint-disable-next-line no-control-regex\n let safe = raw.replace(/[/\\\\<>:\"|?*\\x00-\\x1f]/g, \"_\").trim()\n if (!safe) safe = meta.fileName\n // Split base + extension: use an extension already on the name, else derive\n // one from the mimeType.\n const dot = safe.lastIndexOf(\".\")\n const hasExt = dot > 0 && dot < safe.length - 1\n let base = hasExt ? safe.slice(0, dot) : safe\n const ext = hasExt ? safe.slice(dot + 1) : extForMime(meta.mimeType)\n const suffix = ext ? `.${ext}` : \"\"\n // Bound the total length: common filesystems reject names over ~255 bytes, so\n // a huge app-provided name would make the share's file copy throw. Truncate\n // the base while preserving the extension (mirrors sanitizeSegment's ceiling).\n const MAX_LEN = 120\n if (base.length + suffix.length > MAX_LEN) {\n base = base.slice(0, Math.max(1, MAX_LEN - suffix.length))\n }\n return base + suffix\n}\n\n/**\n * On-disk name for a stored blob: the generated id plus a mime-derived\n * extension when one is known. iOS AVPlayer resolves a local file's format\n * from its path extension (not content sniffing), so an extension-less WAV is\n * unplayable through `session.speaker.play` even though the bytes are valid.\n * Leaves a name that already has an extension untouched.\n */\nexport function withDiskExt(fileName: string, mimeType: string): string {\n if (fileName.includes(\".\")) return fileName\n const ext = extForMime(mimeType)\n return ext ? `${fileName}.${ext}` : fileName\n}\n\n/** Best-effort file extension (no dot) for a MIME type. Inverse of inferMime in BlobStore. */\nexport function extForMime(mime: string): string | undefined {\n const m = (mime || \"\").split(\";\")[0].trim().toLowerCase()\n const map: Record<string, string> = {\n \"application/pdf\": \"pdf\",\n \"application/epub+zip\": \"epub\",\n \"application/zip\": \"zip\",\n \"application/json\": \"json\",\n \"text/plain\": \"txt\",\n \"text/csv\": \"csv\",\n \"text/html\": \"html\",\n \"video/mp4\": \"mp4\",\n \"video/quicktime\": \"mov\",\n \"video/webm\": \"webm\",\n \"audio/mpeg\": \"mp3\",\n \"audio/mp4\": \"m4a\",\n \"audio/wav\": \"wav\",\n \"audio/x-wav\": \"wav\",\n \"audio/wave\": \"wav\",\n \"audio/ogg\": \"ogg\",\n \"image/png\": \"png\",\n \"image/jpeg\": \"jpg\",\n \"image/gif\": \"gif\",\n \"image/webp\": \"webp\",\n \"image/svg+xml\": \"svg\",\n }\n return map[m]\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed-stream provisioning over the cloud-v2 runtime (cloud-client REST):
|
|
3
|
+
*
|
|
4
|
+
* POST /api/camera/stream -> provision (Cloudflare live input)
|
|
5
|
+
* GET /api/camera/stream/:id -> provider's ingest status
|
|
6
|
+
* DELETE /api/camera/stream/:id -> teardown
|
|
7
|
+
*
|
|
8
|
+
* Drop-in replacement for the legacy `v2StreamApi` (which hit the v1 cloud's
|
|
9
|
+
* /api/v2/client/streams/managed on backend_url): same exported shapes, so
|
|
10
|
+
* PhoneStreamCoordinator is unchanged apart from the import. Local miniapps
|
|
11
|
+
* use ONLY this path — no legacy V1 transport.
|
|
12
|
+
*
|
|
13
|
+
* Errors are tagged with stage "provision"/"status"/"teardown" and transport
|
|
14
|
+
* "cloud-rest" so a miniapp sees exactly where and on which leg it broke.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Restream destination. The full stream key is part of the URL — Cloudflare
|
|
18
|
+
* appends nothing on the publish side. `name` is a human label that surfaces
|
|
19
|
+
* in Cloudflare's dashboard but doesn't affect routing.
|
|
20
|
+
*/
|
|
21
|
+
export interface RestreamDestination {
|
|
22
|
+
url: string;
|
|
23
|
+
name?: string;
|
|
24
|
+
}
|
|
25
|
+
/** Caller-facing shape: either a bare URL string or the full object. */
|
|
26
|
+
export type RestreamDestinationInput = string | RestreamDestination;
|
|
27
|
+
export interface ProvisionResult {
|
|
28
|
+
liveInputId: string;
|
|
29
|
+
rtmpUrl: string;
|
|
30
|
+
srtUrl?: string;
|
|
31
|
+
hlsUrl: string;
|
|
32
|
+
dashUrl: string;
|
|
33
|
+
webrtcUrl?: string;
|
|
34
|
+
webrtcPublishUrl?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface CloudflareStatus {
|
|
37
|
+
isConnected: boolean;
|
|
38
|
+
state?: string | null;
|
|
39
|
+
connectedAt?: string;
|
|
40
|
+
lastSeenAt?: string;
|
|
41
|
+
reason?: string;
|
|
42
|
+
}
|
|
43
|
+
export type StreamApiStage = "provision" | "status" | "teardown";
|
|
44
|
+
export declare class StreamApiError extends Error {
|
|
45
|
+
readonly code: string;
|
|
46
|
+
readonly stage: StreamApiStage;
|
|
47
|
+
readonly transport: "cloud-rest";
|
|
48
|
+
constructor(code: string, message: string, stage: StreamApiStage);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Provision a managed stream on the cloud-v2 runtime. Returns ready-to-publish
|
|
52
|
+
* ingest URLs (credentials embedded) plus the playback URLs.
|
|
53
|
+
*/
|
|
54
|
+
export declare function provisionManagedStream(restreamDestinations?: RestreamDestinationInput[]): Promise<ProvisionResult>;
|
|
55
|
+
/** The provider's view of the ingest: is the device's push arriving? */
|
|
56
|
+
export declare function getManagedStreamStatus(liveInputId: string): Promise<CloudflareStatus>;
|
|
57
|
+
/** Tear down the provider stream. */
|
|
58
|
+
export declare function teardownManagedStream(liveInputId: string): Promise<void>;
|
|
59
|
+
//# sourceMappingURL=cloudStreamApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudStreamApi.d.ts","sourceRoot":"","sources":["../../src/services/cloudStreamApi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wEAAwE;AACxE,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,mBAAmB,CAAA;AAEnE,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,OAAO,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAA;AAEhE,qBAAa,cAAe,SAAQ,KAAK;aAGrB,IAAI,EAAE,MAAM;aAEZ,KAAK,EAAE,cAAc;IAJvC,QAAQ,CAAC,SAAS,EAAG,YAAY,CAAS;gBAExB,IAAI,EAAE,MAAM,EAC5B,OAAO,EAAE,MAAM,EACC,KAAK,EAAE,cAAc;CAKxC;AAmBD;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,oBAAoB,CAAC,EAAE,wBAAwB,EAAE,GAChD,OAAO,CAAC,eAAe,CAAC,CAkC1B;AAED,wEAAwE;AACxE,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiB3F;AAED,qCAAqC;AACrC,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9E"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Managed-stream provisioning over the cloud-v2 runtime (cloud-client REST):
|
|
3
|
+
*
|
|
4
|
+
* POST /api/camera/stream -> provision (Cloudflare live input)
|
|
5
|
+
* GET /api/camera/stream/:id -> provider's ingest status
|
|
6
|
+
* DELETE /api/camera/stream/:id -> teardown
|
|
7
|
+
*
|
|
8
|
+
* Drop-in replacement for the legacy `v2StreamApi` (which hit the v1 cloud's
|
|
9
|
+
* /api/v2/client/streams/managed on backend_url): same exported shapes, so
|
|
10
|
+
* PhoneStreamCoordinator is unchanged apart from the import. Local miniapps
|
|
11
|
+
* use ONLY this path — no legacy V1 transport.
|
|
12
|
+
*
|
|
13
|
+
* Errors are tagged with stage "provision"/"status"/"teardown" and transport
|
|
14
|
+
* "cloud-rest" so a miniapp sees exactly where and on which leg it broke.
|
|
15
|
+
*/
|
|
16
|
+
import { cloudClientService as cloudClient } from "./CloudClientService";
|
|
17
|
+
export class StreamApiError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
stage;
|
|
20
|
+
transport = "cloud-rest";
|
|
21
|
+
constructor(code, message, stage) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.code = code;
|
|
24
|
+
this.stage = stage;
|
|
25
|
+
this.name = "StreamApiError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Provision a managed stream on the cloud-v2 runtime. Returns ready-to-publish
|
|
30
|
+
* ingest URLs (credentials embedded) plus the playback URLs.
|
|
31
|
+
*/
|
|
32
|
+
export async function provisionManagedStream(restreamDestinations) {
|
|
33
|
+
let wire;
|
|
34
|
+
try {
|
|
35
|
+
wire = (await cloudClient.startManagedStream(restreamDestinations && restreamDestinations.length > 0 ? { restreamDestinations } : {}));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
throw new StreamApiError("STREAM_PROVISION_FAILED", err instanceof Error ? err.message : String(err), "provision");
|
|
39
|
+
}
|
|
40
|
+
const ingest = wire.ingest ?? {};
|
|
41
|
+
const playback = wire.playback ?? {};
|
|
42
|
+
const rtmpUrl = ingest.rtmpUrl ?? (ingest.url && ingest.streamKey ? `${ingest.url}${ingest.streamKey}` : "");
|
|
43
|
+
if (!playback.hls || !playback.dash) {
|
|
44
|
+
throw new StreamApiError("STREAM_PROVISION_INCOMPLETE", `runtime returned no playback URLs for stream ${wire.streamId}`, "provision");
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
liveInputId: wire.streamId,
|
|
48
|
+
rtmpUrl,
|
|
49
|
+
srtUrl: ingest.srtUrl,
|
|
50
|
+
hlsUrl: playback.hls,
|
|
51
|
+
dashUrl: playback.dash,
|
|
52
|
+
webrtcUrl: playback.webrtc,
|
|
53
|
+
webrtcPublishUrl: ingest.webrtcPublishUrl,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** The provider's view of the ingest: is the device's push arriving? */
|
|
57
|
+
export async function getManagedStreamStatus(liveInputId) {
|
|
58
|
+
try {
|
|
59
|
+
const s = await cloudClient.getManagedStreamStatus(liveInputId);
|
|
60
|
+
return {
|
|
61
|
+
isConnected: s.isConnected,
|
|
62
|
+
state: s.state,
|
|
63
|
+
connectedAt: s.connectedAt,
|
|
64
|
+
lastSeenAt: s.lastSeenAt,
|
|
65
|
+
reason: s.reason,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
throw new StreamApiError("STREAM_STATUS_FAILED", err instanceof Error ? err.message : String(err), "status");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Tear down the provider stream. */
|
|
73
|
+
export async function teardownManagedStream(liveInputId) {
|
|
74
|
+
try {
|
|
75
|
+
await cloudClient.stopManagedStream(liveInputId);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
throw new StreamApiError("STREAM_TEARDOWN_FAILED", err instanceof Error ? err.message : String(err), "teardown");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=cloudStreamApi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudStreamApi.js","sourceRoot":"","sources":["../../src/services/cloudStreamApi.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Managed-stream provisioning over the cloud-v2 runtime (cloud-client REST):\n *\n * POST /api/camera/stream -> provision (Cloudflare live input)\n * GET /api/camera/stream/:id -> provider's ingest status\n * DELETE /api/camera/stream/:id -> teardown\n *\n * Drop-in replacement for the legacy `v2StreamApi` (which hit the v1 cloud's\n * /api/v2/client/streams/managed on backend_url): same exported shapes, so\n * PhoneStreamCoordinator is unchanged apart from the import. Local miniapps\n * use ONLY this path — no legacy V1 transport.\n *\n * Errors are tagged with stage \"provision\"/\"status\"/\"teardown\" and transport\n * \"cloud-rest\" so a miniapp sees exactly where and on which leg it broke.\n */\n\nimport {cloudClientService as cloudClient} from \"./CloudClientService\"\n\n/**\n * Restream destination. The full stream key is part of the URL — Cloudflare\n * appends nothing on the publish side. `name` is a human label that surfaces\n * in Cloudflare's dashboard but doesn't affect routing.\n */\nexport interface RestreamDestination {\n url: string\n name?: string\n}\n\n/** Caller-facing shape: either a bare URL string or the full object. */\nexport type RestreamDestinationInput = string | RestreamDestination\n\nexport interface ProvisionResult {\n liveInputId: string\n rtmpUrl: string\n srtUrl?: string\n hlsUrl: string\n dashUrl: string\n webrtcUrl?: string\n webrtcPublishUrl?: string\n}\n\nexport interface CloudflareStatus {\n isConnected: boolean\n state?: string | null\n connectedAt?: string\n lastSeenAt?: string\n reason?: string\n}\n\nexport type StreamApiStage = \"provision\" | \"status\" | \"teardown\"\n\nexport class StreamApiError extends Error {\n readonly transport = \"cloud-rest\" as const\n constructor(\n public readonly code: string,\n message: string,\n public readonly stage: StreamApiStage,\n ) {\n super(message)\n this.name = \"StreamApiError\"\n }\n}\n\n/** The cloud-v2 runtime's ManagedStream wire shape (open records, see protocol). */\ninterface ManagedStreamWire {\n streamId: string\n ingest: {\n url?: string\n streamKey?: string\n rtmpUrl?: string\n srtUrl?: string\n webrtcPublishUrl?: string\n }\n playback: {\n hls?: string\n dash?: string\n webrtc?: string\n }\n}\n\n/**\n * Provision a managed stream on the cloud-v2 runtime. Returns ready-to-publish\n * ingest URLs (credentials embedded) plus the playback URLs.\n */\nexport async function provisionManagedStream(\n restreamDestinations?: RestreamDestinationInput[],\n): Promise<ProvisionResult> {\n let wire: ManagedStreamWire\n try {\n wire = (await cloudClient.startManagedStream(\n restreamDestinations && restreamDestinations.length > 0 ? {restreamDestinations} : {},\n )) as ManagedStreamWire\n } catch (err) {\n throw new StreamApiError(\n \"STREAM_PROVISION_FAILED\",\n err instanceof Error ? err.message : String(err),\n \"provision\",\n )\n }\n\n const ingest = wire.ingest ?? {}\n const playback = wire.playback ?? {}\n const rtmpUrl = ingest.rtmpUrl ?? (ingest.url && ingest.streamKey ? `${ingest.url}${ingest.streamKey}` : \"\")\n if (!playback.hls || !playback.dash) {\n throw new StreamApiError(\n \"STREAM_PROVISION_INCOMPLETE\",\n `runtime returned no playback URLs for stream ${wire.streamId}`,\n \"provision\",\n )\n }\n\n return {\n liveInputId: wire.streamId,\n rtmpUrl,\n srtUrl: ingest.srtUrl,\n hlsUrl: playback.hls,\n dashUrl: playback.dash,\n webrtcUrl: playback.webrtc,\n webrtcPublishUrl: ingest.webrtcPublishUrl,\n }\n}\n\n/** The provider's view of the ingest: is the device's push arriving? */\nexport async function getManagedStreamStatus(liveInputId: string): Promise<CloudflareStatus> {\n try {\n const s = await cloudClient.getManagedStreamStatus(liveInputId)\n return {\n isConnected: s.isConnected,\n state: s.state,\n connectedAt: s.connectedAt,\n lastSeenAt: s.lastSeenAt,\n reason: s.reason,\n }\n } catch (err) {\n throw new StreamApiError(\n \"STREAM_STATUS_FAILED\",\n err instanceof Error ? err.message : String(err),\n \"status\",\n )\n }\n}\n\n/** Tear down the provider stream. */\nexport async function teardownManagedStream(liveInputId: string): Promise<void> {\n try {\n await cloudClient.stopManagedStream(liveInputId)\n } catch (err) {\n throw new StreamApiError(\n \"STREAM_TEARDOWN_FAILED\",\n err instanceof Error ? err.message : String(err),\n \"teardown\",\n )\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clock skew detection for gallery sync (phone vs glasses).
|
|
3
|
+
* Phone pushes time to glasses only when skew is detected during sync.
|
|
4
|
+
*/
|
|
5
|
+
export declare const CLOCK_SKEW_TOLERANCE_MS = 60000;
|
|
6
|
+
export type ClockSkewReason = "watermark_ahead_of_glasses" | "wall_clock_drift" | "";
|
|
7
|
+
export interface ClockSkewResult {
|
|
8
|
+
skewed: boolean;
|
|
9
|
+
reason: ClockSkewReason;
|
|
10
|
+
}
|
|
11
|
+
export declare function detectClockSkew(phoneNow: number, glassesServerTime: number, lastSyncTime: number, toleranceMs?: number): ClockSkewResult;
|
|
12
|
+
export declare function isSyncManifestEmpty(syncData: {
|
|
13
|
+
api_version?: number;
|
|
14
|
+
captures?: unknown[];
|
|
15
|
+
changed_files?: unknown[];
|
|
16
|
+
}): boolean;
|
|
17
|
+
//# sourceMappingURL=gallerySyncClock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gallerySyncClock.d.ts","sourceRoot":"","sources":["../../src/services/gallerySyncClock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,uBAAuB,QAAS,CAAA;AAE7C,MAAM,MAAM,eAAe,GAAG,4BAA4B,GAAG,kBAAkB,GAAG,EAAE,CAAA;AAEpF,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,WAAW,GAAE,MAAgC,GAC5C,eAAe,CAQjB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAA;CAC1B,GAAG,OAAO,CAKV"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clock skew detection for gallery sync (phone vs glasses).
|
|
3
|
+
* Phone pushes time to glasses only when skew is detected during sync.
|
|
4
|
+
*/
|
|
5
|
+
export const CLOCK_SKEW_TOLERANCE_MS = 60_000;
|
|
6
|
+
export function detectClockSkew(phoneNow, glassesServerTime, lastSyncTime, toleranceMs = CLOCK_SKEW_TOLERANCE_MS) {
|
|
7
|
+
if (lastSyncTime > glassesServerTime + toleranceMs) {
|
|
8
|
+
return { skewed: true, reason: "watermark_ahead_of_glasses" };
|
|
9
|
+
}
|
|
10
|
+
if (Math.abs(phoneNow - glassesServerTime) > toleranceMs) {
|
|
11
|
+
return { skewed: true, reason: "wall_clock_drift" };
|
|
12
|
+
}
|
|
13
|
+
return { skewed: false, reason: "" };
|
|
14
|
+
}
|
|
15
|
+
export function isSyncManifestEmpty(syncData) {
|
|
16
|
+
if ((syncData.api_version || 0) >= 2 && syncData.captures && syncData.captures.length > 0) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return !syncData.changed_files || syncData.changed_files.length === 0;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=gallerySyncClock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gallerySyncClock.js","sourceRoot":"","sources":["../../src/services/gallerySyncClock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAA;AAS7C,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,iBAAyB,EACzB,YAAoB,EACpB,cAAsB,uBAAuB;IAE7C,IAAI,YAAY,GAAG,iBAAiB,GAAG,WAAW,EAAE,CAAC;QACnD,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,4BAA4B,EAAC,CAAA;IAC7D,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,iBAAiB,CAAC,GAAG,WAAW,EAAE,CAAC;QACzD,OAAO,EAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,kBAAkB,EAAC,CAAA;IACnD,CAAC;IACD,OAAO,EAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAC,CAAA;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAInC;IACC,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1F,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,CAAC,QAAQ,CAAC,aAAa,IAAI,QAAQ,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,CAAA;AACvE,CAAC","sourcesContent":["/**\n * Clock skew detection for gallery sync (phone vs glasses).\n * Phone pushes time to glasses only when skew is detected during sync.\n */\n\nexport const CLOCK_SKEW_TOLERANCE_MS = 60_000\n\nexport type ClockSkewReason = \"watermark_ahead_of_glasses\" | \"wall_clock_drift\" | \"\"\n\nexport interface ClockSkewResult {\n skewed: boolean\n reason: ClockSkewReason\n}\n\nexport function detectClockSkew(\n phoneNow: number,\n glassesServerTime: number,\n lastSyncTime: number,\n toleranceMs: number = CLOCK_SKEW_TOLERANCE_MS,\n): ClockSkewResult {\n if (lastSyncTime > glassesServerTime + toleranceMs) {\n return {skewed: true, reason: \"watermark_ahead_of_glasses\"}\n }\n if (Math.abs(phoneNow - glassesServerTime) > toleranceMs) {\n return {skewed: true, reason: \"wall_clock_drift\"}\n }\n return {skewed: false, reason: \"\"}\n}\n\nexport function isSyncManifestEmpty(syncData: {\n api_version?: number\n captures?: unknown[]\n changed_files?: unknown[]\n}): boolean {\n if ((syncData.api_version || 0) >= 2 && syncData.captures && syncData.captures.length > 0) {\n return false\n }\n return !syncData.changed_files || syncData.changed_files.length === 0\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push phone time to glasses only when clock skew is detected (gallery sync, OTA, etc.).
|
|
3
|
+
*/
|
|
4
|
+
export declare const CLOCK_SETTLE_MS = 500;
|
|
5
|
+
/** @internal test-only */
|
|
6
|
+
export declare function resetOtaClockFixCooldownForTests(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Set glasses system clock from phone when skew is detected.
|
|
9
|
+
*/
|
|
10
|
+
export declare function fixGlassesClockIfSkewed(glassesServerTime: number, lastSyncTime?: number): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* After glasses report OTA failure due to clock skew, fix time and restart
|
|
13
|
+
* through the normal phone-driven ota_start path.
|
|
14
|
+
*/
|
|
15
|
+
export declare function handleOtaClockSkewFromGlasses(errorCode: string | undefined, glassesTimeMs?: number): Promise<boolean>;
|
|
16
|
+
/**
|
|
17
|
+
* Proactive fix when version_info includes glasses system_time_ms before OTA manifest checks.
|
|
18
|
+
*/
|
|
19
|
+
export declare function maybeFixGlassesClockFromVersionInfo(systemTimeMs: number | undefined): Promise<boolean>;
|
|
20
|
+
//# sourceMappingURL=glassesClockSync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glassesClockSync.d.ts","sourceRoot":"","sources":["../../src/services/glassesClockSync.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,eAAO,MAAM,eAAe,MAAM,CAAA;AASlC,0BAA0B;AAC1B,wBAAgB,gCAAgC,IAAI,IAAI,CAGvD;AAMD;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,iBAAiB,EAAE,MAAM,EAAE,YAAY,SAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAS3G;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CACjD,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CA+ClB;AAED;;GAEG;AACH,wBAAsB,mCAAmC,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAW5G"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Push phone time to glasses only when clock skew is detected (gallery sync, OTA, etc.).
|
|
3
|
+
*/
|
|
4
|
+
import BluetoothSdk from "@mentra/bluetooth-sdk/internal";
|
|
5
|
+
import { BgTimer } from "../utils/timers";
|
|
6
|
+
import { useGlassesStore } from "../stores/glasses";
|
|
7
|
+
import { getAsgOtaVersionUrl } from "./asgOtaVersionUrl";
|
|
8
|
+
import { detectClockSkew } from "./gallerySyncClock";
|
|
9
|
+
export const CLOCK_SETTLE_MS = 500;
|
|
10
|
+
const OTA_CLOCK_FIX_COOLDOWN_MS = 30_000;
|
|
11
|
+
let lastOtaClockFixAt = 0;
|
|
12
|
+
// Coalesce concurrent OTA clock-fix attempts. Glasses can emit two clock_skew events
|
|
13
|
+
// back-to-back during BLE handshake; without this guard both would await the BLE fix
|
|
14
|
+
// + retry pair before either updated `lastOtaClockFixAt`.
|
|
15
|
+
let inflightOtaClockFix = null;
|
|
16
|
+
/** @internal test-only */
|
|
17
|
+
export function resetOtaClockFixCooldownForTests() {
|
|
18
|
+
lastOtaClockFixAt = 0;
|
|
19
|
+
inflightOtaClockFix = null;
|
|
20
|
+
}
|
|
21
|
+
function delay(ms) {
|
|
22
|
+
return new Promise((resolve) => BgTimer.setTimeout(resolve, ms));
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Set glasses system clock from phone when skew is detected.
|
|
26
|
+
*/
|
|
27
|
+
export async function fixGlassesClockIfSkewed(glassesServerTime, lastSyncTime = 0) {
|
|
28
|
+
const { skewed, reason } = detectClockSkew(Date.now(), glassesServerTime, lastSyncTime);
|
|
29
|
+
if (!skewed) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
console.log(`[GlassesClockSync] ⏰ Clock skew detected (${reason}) — setting glasses time from phone`);
|
|
33
|
+
await BluetoothSdk.setSystemTime(Date.now());
|
|
34
|
+
await delay(CLOCK_SETTLE_MS);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* After glasses report OTA failure due to clock skew, fix time and restart
|
|
39
|
+
* through the normal phone-driven ota_start path.
|
|
40
|
+
*/
|
|
41
|
+
export async function handleOtaClockSkewFromGlasses(errorCode, glassesTimeMs) {
|
|
42
|
+
if (Date.now() - lastOtaClockFixAt < OTA_CLOCK_FIX_COOLDOWN_MS) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
const hasGlassesTime = typeof glassesTimeMs === "number" && Number.isFinite(glassesTimeMs) && glassesTimeMs > 0;
|
|
46
|
+
if (errorCode === "ssl_error") {
|
|
47
|
+
if (!hasGlassesTime) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
const { skewed } = detectClockSkew(Date.now(), glassesTimeMs, 0);
|
|
51
|
+
if (!skewed) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
console.log("[GlassesClockSync] ⏰ OTA ssl_error with wall-clock drift — treating as clock skew");
|
|
55
|
+
}
|
|
56
|
+
else if (errorCode !== "clock_skew") {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
// Coalesce concurrent attempts: if a fix is already in flight, await its result instead
|
|
60
|
+
// of racing it through the cooldown guard.
|
|
61
|
+
if (inflightOtaClockFix) {
|
|
62
|
+
return inflightOtaClockFix;
|
|
63
|
+
}
|
|
64
|
+
const glassesTime = hasGlassesTime ? glassesTimeMs : Date.now() - 86_400_000;
|
|
65
|
+
inflightOtaClockFix = (async () => {
|
|
66
|
+
try {
|
|
67
|
+
const fixed = await fixGlassesClockIfSkewed(glassesTime, 0);
|
|
68
|
+
if (!fixed) {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
lastOtaClockFixAt = Date.now();
|
|
72
|
+
const { buildNumber, otaVersionUrl } = useGlassesStore.getState();
|
|
73
|
+
const manifestUrl = getAsgOtaVersionUrl(otaVersionUrl, buildNumber);
|
|
74
|
+
console.log("[GlassesClockSync] ⏰ Restarting OTA with ota_start after clock fix");
|
|
75
|
+
await BluetoothSdk.startOtaUpdate(manifestUrl);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
inflightOtaClockFix = null;
|
|
80
|
+
}
|
|
81
|
+
})();
|
|
82
|
+
return inflightOtaClockFix;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Proactive fix when version_info includes glasses system_time_ms before OTA manifest checks.
|
|
86
|
+
*/
|
|
87
|
+
export async function maybeFixGlassesClockFromVersionInfo(systemTimeMs) {
|
|
88
|
+
if (typeof systemTimeMs !== "number" || systemTimeMs <= 0) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const fixed = await fixGlassesClockIfSkewed(systemTimeMs, 0);
|
|
92
|
+
if (!fixed) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=glassesClockSync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glassesClockSync.js","sourceRoot":"","sources":["../../src/services/glassesClockSync.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Push phone time to glasses only when clock skew is detected (gallery sync, OTA, etc.).\n */\n\nimport BluetoothSdk from \"@mentra/bluetooth-sdk/internal\"\nimport {BgTimer} from \"../utils/timers\"\nimport {useGlassesStore} from \"../stores/glasses\"\n\nimport {getAsgOtaVersionUrl} from \"./asgOtaVersionUrl\"\nimport {detectClockSkew} from \"./gallerySyncClock\"\n\nexport const CLOCK_SETTLE_MS = 500\n\nconst OTA_CLOCK_FIX_COOLDOWN_MS = 30_000\nlet lastOtaClockFixAt = 0\n// Coalesce concurrent OTA clock-fix attempts. Glasses can emit two clock_skew events\n// back-to-back during BLE handshake; without this guard both would await the BLE fix\n// + retry pair before either updated `lastOtaClockFixAt`.\nlet inflightOtaClockFix: Promise<boolean> | null = null\n\n/** @internal test-only */\nexport function resetOtaClockFixCooldownForTests(): void {\n lastOtaClockFixAt = 0\n inflightOtaClockFix = null\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => BgTimer.setTimeout(resolve, ms))\n}\n\n/**\n * Set glasses system clock from phone when skew is detected.\n */\nexport async function fixGlassesClockIfSkewed(glassesServerTime: number, lastSyncTime = 0): Promise<boolean> {\n const {skewed, reason} = detectClockSkew(Date.now(), glassesServerTime, lastSyncTime)\n if (!skewed) {\n return false\n }\n console.log(`[GlassesClockSync] ⏰ Clock skew detected (${reason}) — setting glasses time from phone`)\n await BluetoothSdk.setSystemTime(Date.now())\n await delay(CLOCK_SETTLE_MS)\n return true\n}\n\n/**\n * After glasses report OTA failure due to clock skew, fix time and restart\n * through the normal phone-driven ota_start path.\n */\nexport async function handleOtaClockSkewFromGlasses(\n errorCode: string | undefined,\n glassesTimeMs?: number,\n): Promise<boolean> {\n if (Date.now() - lastOtaClockFixAt < OTA_CLOCK_FIX_COOLDOWN_MS) {\n return false\n }\n\n const hasGlassesTime = typeof glassesTimeMs === \"number\" && Number.isFinite(glassesTimeMs) && glassesTimeMs > 0\n\n if (errorCode === \"ssl_error\") {\n if (!hasGlassesTime) {\n return false\n }\n const {skewed} = detectClockSkew(Date.now(), glassesTimeMs, 0)\n if (!skewed) {\n return false\n }\n console.log(\"[GlassesClockSync] ⏰ OTA ssl_error with wall-clock drift — treating as clock skew\")\n } else if (errorCode !== \"clock_skew\") {\n return false\n }\n\n // Coalesce concurrent attempts: if a fix is already in flight, await its result instead\n // of racing it through the cooldown guard.\n if (inflightOtaClockFix) {\n return inflightOtaClockFix\n }\n\n const glassesTime = hasGlassesTime ? glassesTimeMs : Date.now() - 86_400_000\n\n inflightOtaClockFix = (async () => {\n try {\n const fixed = await fixGlassesClockIfSkewed(glassesTime, 0)\n if (!fixed) {\n return false\n }\n\n lastOtaClockFixAt = Date.now()\n const {buildNumber, otaVersionUrl} = useGlassesStore.getState()\n const manifestUrl = getAsgOtaVersionUrl(otaVersionUrl, buildNumber)\n console.log(\"[GlassesClockSync] ⏰ Restarting OTA with ota_start after clock fix\")\n await BluetoothSdk.startOtaUpdate(manifestUrl)\n return true\n } finally {\n inflightOtaClockFix = null\n }\n })()\n\n return inflightOtaClockFix\n}\n\n/**\n * Proactive fix when version_info includes glasses system_time_ms before OTA manifest checks.\n */\nexport async function maybeFixGlassesClockFromVersionInfo(systemTimeMs: number | undefined): Promise<boolean> {\n if (typeof systemTimeMs !== \"number\" || systemTimeMs <= 0) {\n return false\n }\n\n const fixed = await fixGlassesClockIfSkewed(systemTimeMs, 0)\n if (!fixed) {\n return false\n }\n\n return true\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helper extracted from `AppRegistry.checkManifestVersions` so it
|
|
3
|
+
* can be unit-tested without dragging in the `expo-file-system`
|
|
4
|
+
* transitively-React-Native dependency tree.
|
|
5
|
+
*
|
|
6
|
+
* Returns `{ok: true}` when the manifest is compatible with the host,
|
|
7
|
+
* or `{ok: false, reason}` with a user-facing string. Manifests missing
|
|
8
|
+
* either field pass through (legacy single-bundle bundles).
|
|
9
|
+
*
|
|
10
|
+
* `sdkVersion` is the SDK ABI the bundle targets; `minHostVersion` is
|
|
11
|
+
* the host floor the miniapp requires. Both must satisfy semver-coerce.
|
|
12
|
+
* Strings that don't coerce are treated as "unspecified" — the
|
|
13
|
+
* CLI's validateManifest catches malformed inputs at install time so
|
|
14
|
+
* this helper stays permissive at the policy layer.
|
|
15
|
+
*/
|
|
16
|
+
export declare function checkManifestVersions(manifest: {
|
|
17
|
+
sdkVersion?: string;
|
|
18
|
+
minHostVersion?: string;
|
|
19
|
+
} | null, options: {
|
|
20
|
+
hostVersion: string;
|
|
21
|
+
supportedSdkRange: string;
|
|
22
|
+
}): {
|
|
23
|
+
ok: true;
|
|
24
|
+
} | {
|
|
25
|
+
ok: false;
|
|
26
|
+
reason: string;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=manifestVersionGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestVersionGate.d.ts","sourceRoot":"","sources":["../../src/services/manifestVersionGate.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAC,GAAG,IAAI,EAC/D,OAAO,EAAE;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAC,GACxD;IAAC,EAAE,EAAE,IAAI,CAAA;CAAC,GAAG;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAC,CAsB1C"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import semver from "semver";
|
|
2
|
+
/**
|
|
3
|
+
* Pure helper extracted from `AppRegistry.checkManifestVersions` so it
|
|
4
|
+
* can be unit-tested without dragging in the `expo-file-system`
|
|
5
|
+
* transitively-React-Native dependency tree.
|
|
6
|
+
*
|
|
7
|
+
* Returns `{ok: true}` when the manifest is compatible with the host,
|
|
8
|
+
* or `{ok: false, reason}` with a user-facing string. Manifests missing
|
|
9
|
+
* either field pass through (legacy single-bundle bundles).
|
|
10
|
+
*
|
|
11
|
+
* `sdkVersion` is the SDK ABI the bundle targets; `minHostVersion` is
|
|
12
|
+
* the host floor the miniapp requires. Both must satisfy semver-coerce.
|
|
13
|
+
* Strings that don't coerce are treated as "unspecified" — the
|
|
14
|
+
* CLI's validateManifest catches malformed inputs at install time so
|
|
15
|
+
* this helper stays permissive at the policy layer.
|
|
16
|
+
*/
|
|
17
|
+
export function checkManifestVersions(manifest, options) {
|
|
18
|
+
if (!manifest)
|
|
19
|
+
return { ok: true };
|
|
20
|
+
if (manifest.minHostVersion) {
|
|
21
|
+
const cleanHost = semver.valid(semver.coerce(options.hostVersion) ?? options.hostVersion);
|
|
22
|
+
const cleanMin = semver.valid(semver.coerce(manifest.minHostVersion) ?? manifest.minHostVersion);
|
|
23
|
+
if (cleanHost && cleanMin && semver.lt(cleanHost, cleanMin)) {
|
|
24
|
+
return {
|
|
25
|
+
ok: false,
|
|
26
|
+
reason: `Requires MentraOS ${manifest.minHostVersion}+; this host is ${options.hostVersion}.`,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (manifest.sdkVersion) {
|
|
31
|
+
const cleanSdk = semver.valid(semver.coerce(manifest.sdkVersion) ?? manifest.sdkVersion);
|
|
32
|
+
if (cleanSdk && !semver.satisfies(cleanSdk, options.supportedSdkRange)) {
|
|
33
|
+
return {
|
|
34
|
+
ok: false,
|
|
35
|
+
reason: `Built for SDK ${manifest.sdkVersion}; host supports ${options.supportedSdkRange}.`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { ok: true };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=manifestVersionGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestVersionGate.js","sourceRoot":"","sources":["../../src/services/manifestVersionGate.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAE3B;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAA+D,EAC/D,OAAyD;IAEzD,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAC,EAAE,EAAE,IAAI,EAAC,CAAA;IAChC,IAAI,QAAQ,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,CAAA;QACzF,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,QAAQ,CAAC,cAAc,CAAC,CAAA;QAChG,IAAI,SAAS,IAAI,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC;YAC5D,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,qBAAqB,QAAQ,CAAC,cAAc,mBAAmB,OAAO,CAAC,WAAW,GAAG;aAC9F,CAAA;QACH,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAA;QACxF,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;YACvE,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,iBAAiB,QAAQ,CAAC,UAAU,mBAAmB,OAAO,CAAC,iBAAiB,GAAG;aAC5F,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAC,EAAE,EAAE,IAAI,EAAC,CAAA;AACnB,CAAC","sourcesContent":["import semver from \"semver\"\n\n/**\n * Pure helper extracted from `AppRegistry.checkManifestVersions` so it\n * can be unit-tested without dragging in the `expo-file-system`\n * transitively-React-Native dependency tree.\n *\n * Returns `{ok: true}` when the manifest is compatible with the host,\n * or `{ok: false, reason}` with a user-facing string. Manifests missing\n * either field pass through (legacy single-bundle bundles).\n *\n * `sdkVersion` is the SDK ABI the bundle targets; `minHostVersion` is\n * the host floor the miniapp requires. Both must satisfy semver-coerce.\n * Strings that don't coerce are treated as \"unspecified\" — the\n * CLI's validateManifest catches malformed inputs at install time so\n * this helper stays permissive at the policy layer.\n */\nexport function checkManifestVersions(\n manifest: {sdkVersion?: string; minHostVersion?: string} | null,\n options: {hostVersion: string; supportedSdkRange: string},\n): {ok: true} | {ok: false; reason: string} {\n if (!manifest) return {ok: true}\n if (manifest.minHostVersion) {\n const cleanHost = semver.valid(semver.coerce(options.hostVersion) ?? options.hostVersion)\n const cleanMin = semver.valid(semver.coerce(manifest.minHostVersion) ?? manifest.minHostVersion)\n if (cleanHost && cleanMin && semver.lt(cleanHost, cleanMin)) {\n return {\n ok: false,\n reason: `Requires MentraOS ${manifest.minHostVersion}+; this host is ${options.hostVersion}.`,\n }\n }\n }\n if (manifest.sdkVersion) {\n const cleanSdk = semver.valid(semver.coerce(manifest.sdkVersion) ?? manifest.sdkVersion)\n if (cleanSdk && !semver.satisfies(cleanSdk, options.supportedSdkRange)) {\n return {\n ok: false,\n reason: `Built for SDK ${manifest.sdkVersion}; host supports ${options.supportedSdkRange}.`,\n }\n }\n }\n return {ok: true}\n}\n"]}
|