@mentra/engine 0.1.0-dev.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 +57 -0
- package/build/facades/dev.d.ts.map +1 -0
- package/build/facades/dev.js +187 -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 +23 -0
- package/build/facades/permissions.d.ts.map +1 -0
- package/build/facades/permissions.js +145 -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 +66 -0
- package/build/internal.d.ts.map +1 -0
- package/build/internal.js +89 -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 +303 -0
- package/build/services/AppRegistry.d.ts.map +1 -0
- package/build/services/AppRegistry.js +1029 -0
- package/build/services/AppRegistry.js.map +1 -0
- package/build/services/AudioCloudUplink.d.ts +3 -0
- package/build/services/AudioCloudUplink.d.ts.map +1 -0
- package/build/services/AudioCloudUplink.js +33 -0
- package/build/services/AudioCloudUplink.js.map +1 -0
- package/build/services/AudioPlaybackService.d.ts +144 -0
- package/build/services/AudioPlaybackService.d.ts.map +1 -0
- package/build/services/AudioPlaybackService.js +533 -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 +627 -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 +433 -0
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -0
- package/build/services/LocalMiniappRuntime.js +3561 -0
- package/build/services/LocalMiniappRuntime.js.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts +54 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -0
- package/build/services/LocalSttFallbackCoordinator.js +131 -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/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/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 +86 -0
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -0
- package/build/services/PhonePhotoCoordinator.js +274 -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/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/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 +165 -0
- package/build/services/asg/asgCameraApi.d.ts.map +1 -0
- package/build/services/asg/asgCameraApi.js +997 -0
- package/build/services/asg/asgCameraApi.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/gallerySettingsService.d.ts +19 -0
- package/build/services/asg/gallerySettingsService.d.ts.map +1 -0
- package/build/services/asg/gallerySettingsService.js +51 -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 +1839 -0
- package/build/services/asg/gallerySyncService.js.map +1 -0
- package/build/services/asg/localStorageService.d.ts +128 -0
- package/build/services/asg/localStorageService.d.ts.map +1 -0
- package/build/services/asg/localStorageService.js +423 -0
- package/build/services/asg/localStorageService.js.map +1 -0
- package/build/services/asg/mediaProcessingQueue.d.ts +60 -0
- package/build/services/asg/mediaProcessingQueue.d.ts.map +1 -0
- package/build/services/asg/mediaProcessingQueue.js +320 -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 +915 -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 +46 -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 +34 -0
- package/build/utils/permissions/MediaLibraryPermissions.d.ts.map +1 -0
- package/build/utils/permissions/MediaLibraryPermissions.js +122 -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 +119 -0
- package/src/devtools.ts +13 -0
- package/src/engine.ts +173 -0
- package/src/facades/dev.ts +197 -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 +151 -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 +158 -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 +1139 -0
- package/src/services/AudioCloudUplink.ts +34 -0
- package/src/services/AudioPlaybackService.ts +624 -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 +668 -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 +4038 -0
- package/src/services/LocalSttFallbackCoordinator.ts +140 -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/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/PhoneLocationService.ts +122 -0
- package/src/services/PhoneNotificationsSync.ts +44 -0
- package/src/services/PhonePhotoCoordinator.ts +337 -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/StreamLifecycleController.ts +213 -0
- package/src/services/TTSModelManager.ts +466 -0
- package/src/services/WebviewBridge.ts +50 -0
- package/src/services/asg/GalleryMediaIntegrityReportService.ts +70 -0
- package/src/services/asg/asgCameraApi.ts +1204 -0
- package/src/services/asg/galleryMediaValidation.ts +183 -0
- package/src/services/asg/galleryNotices.ts +60 -0
- package/src/services/asg/gallerySettingsService.ts +65 -0
- package/src/services/asg/gallerySyncNotifications.ts +236 -0
- package/src/services/asg/gallerySyncService.ts +2167 -0
- package/src/services/asg/localStorageService.ts +497 -0
- package/src/services/asg/mediaProcessingQueue.ts +371 -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 +993 -0
- package/src/types/applet.ts +112 -0
- package/src/types/asg.ts +51 -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 +130 -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,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media Processing Queue
|
|
3
|
+
*
|
|
4
|
+
* Decouples media processing (HDR merge, color correction, stabilization, camera roll save)
|
|
5
|
+
* from the download pipeline. Downloads push items here; processing runs independently.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as RNFS from "@dr.pogodin/react-native-fs"
|
|
9
|
+
import CrustModule from "@mentra/crust"
|
|
10
|
+
|
|
11
|
+
import {asgCameraApi} from "./asgCameraApi"
|
|
12
|
+
import {localStorageService} from "./localStorageService"
|
|
13
|
+
import {INVALID_DOWNLOADED_MEDIA, validateDownloadedMediaFile} from "./galleryMediaValidation"
|
|
14
|
+
import {reportInvalidGalleryMedia} from "./GalleryMediaIntegrityReportService"
|
|
15
|
+
import {useGallerySyncStore} from "../../stores/gallerySync"
|
|
16
|
+
import {BgTimer} from "../../utils/timers"
|
|
17
|
+
import {MediaLibraryPermissions} from "../../utils/permissions/MediaLibraryPermissions"
|
|
18
|
+
|
|
19
|
+
const TAG = "[MediaProcessingQueue]"
|
|
20
|
+
|
|
21
|
+
export interface ProcessingItem {
|
|
22
|
+
/** Unique ID — capture_id (v2) or file name (v1) */
|
|
23
|
+
id: string
|
|
24
|
+
type: "photo" | "video"
|
|
25
|
+
/** Path to the primary downloaded file */
|
|
26
|
+
primaryPath: string
|
|
27
|
+
/** HDR bracket paths (v2 only) */
|
|
28
|
+
bracketPaths?: string[]
|
|
29
|
+
/** IMU sidecar path for video stabilization */
|
|
30
|
+
sidecarPath?: string
|
|
31
|
+
/** Thumbnail base64 data */
|
|
32
|
+
thumbnailData?: string
|
|
33
|
+
/** Capture directory for saving thumbnail */
|
|
34
|
+
captureDir?: string
|
|
35
|
+
/** Original capture timestamp */
|
|
36
|
+
timestamp?: number
|
|
37
|
+
/** Total file size */
|
|
38
|
+
totalSize: number
|
|
39
|
+
/** Video duration in ms */
|
|
40
|
+
duration?: number
|
|
41
|
+
/** Glasses model */
|
|
42
|
+
glassesModel?: string
|
|
43
|
+
/** Whether to process (lens/color/stabilization) */
|
|
44
|
+
shouldProcess: boolean
|
|
45
|
+
/** Whether to auto-save to camera roll */
|
|
46
|
+
shouldAutoSave: boolean
|
|
47
|
+
/** Pre-downloaded thumbnail path (v1 legacy sync) */
|
|
48
|
+
thumbnailPath?: string
|
|
49
|
+
/** File names to delete from glasses after processing completes */
|
|
50
|
+
deleteFromGlasses?: string[]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class MediaProcessingQueue {
|
|
54
|
+
private queue: ProcessingItem[] = []
|
|
55
|
+
private isRunning = false
|
|
56
|
+
private aborted = false
|
|
57
|
+
private generation = 0 // C2: incremented on reset() to invalidate stale processLoop()
|
|
58
|
+
|
|
59
|
+
/** Add an item to the processing queue. Starts processing if not already running. */
|
|
60
|
+
enqueue(item: ProcessingItem): void {
|
|
61
|
+
this.queue.push(item)
|
|
62
|
+
console.log(`${TAG} Enqueued ${item.id} (${item.type}), queue size: ${this.queue.length}`)
|
|
63
|
+
|
|
64
|
+
// Only mark as processing if we'll actually process this item
|
|
65
|
+
if (item.shouldProcess) {
|
|
66
|
+
const store = useGallerySyncStore.getState()
|
|
67
|
+
store.onFileProcessing(item.id)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!this.isRunning) {
|
|
71
|
+
this.processLoop()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Cancel all pending processing. */
|
|
76
|
+
abort(): void {
|
|
77
|
+
this.aborted = true
|
|
78
|
+
this.queue = []
|
|
79
|
+
console.log(`${TAG} Aborted`)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Reset state for a new sync session. */
|
|
83
|
+
reset(): void {
|
|
84
|
+
this.queue = []
|
|
85
|
+
this.isRunning = false
|
|
86
|
+
this.aborted = false
|
|
87
|
+
this.generation++ // C2: invalidate any running processLoop
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Returns true if there are items queued or currently processing. */
|
|
91
|
+
get hasPending(): boolean {
|
|
92
|
+
return this.queue.length > 0 || this.isRunning
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Returns a promise that resolves when the queue is fully drained, or rejects on timeout. */
|
|
96
|
+
waitUntilDrained(timeoutMs: number = 600000): Promise<void> {
|
|
97
|
+
if (!this.hasPending) return Promise.resolve()
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
const deadline = Date.now() + timeoutMs
|
|
100
|
+
const check = () => {
|
|
101
|
+
if (!this.hasPending || this.aborted) {
|
|
102
|
+
resolve()
|
|
103
|
+
} else if (Date.now() >= deadline) {
|
|
104
|
+
console.error(`${TAG} waitUntilDrained timed out after ${timeoutMs}ms, aborting queue`)
|
|
105
|
+
this.abort()
|
|
106
|
+
reject(new Error(`Processing queue timed out after ${timeoutMs / 1000}s`))
|
|
107
|
+
} else {
|
|
108
|
+
BgTimer.setTimeout(check, 200)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
check()
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Process items one at a time. */
|
|
116
|
+
private async processLoop(): Promise<void> {
|
|
117
|
+
if (this.isRunning) return
|
|
118
|
+
this.isRunning = true
|
|
119
|
+
const myGeneration = this.generation // C2: capture generation to detect reset()
|
|
120
|
+
|
|
121
|
+
while (this.queue.length > 0 && !this.aborted && this.generation === myGeneration) {
|
|
122
|
+
const item = this.queue.shift()!
|
|
123
|
+
let processFailed = false
|
|
124
|
+
try {
|
|
125
|
+
await this.processItem(item)
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error(`${TAG} Error processing ${item.id}:`, error)
|
|
128
|
+
processFailed = true
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Exit if generation changed (reset was called during processing)
|
|
132
|
+
if (this.generation !== myGeneration) break
|
|
133
|
+
|
|
134
|
+
const store = useGallerySyncStore.getState()
|
|
135
|
+
if (!processFailed) {
|
|
136
|
+
// Success: increment processedFiles and remove from processingFiles set.
|
|
137
|
+
store.onFileProcessed(item.id)
|
|
138
|
+
} else {
|
|
139
|
+
// Failure: processItem already called onFileFailed. Calling onFileProcessed
|
|
140
|
+
// here would double-count the item (counted as both failed AND processed).
|
|
141
|
+
// Still clear the processingFiles entry so the UI doesn't show it as in-progress.
|
|
142
|
+
const current = store.processingFiles
|
|
143
|
+
if (current.has(item.id)) {
|
|
144
|
+
const newSet = new Set(current)
|
|
145
|
+
newSet.delete(item.id)
|
|
146
|
+
useGallerySyncStore.setState({processingFiles: newSet})
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Only clear isRunning if this loop owns the current generation
|
|
152
|
+
if (this.generation === myGeneration) {
|
|
153
|
+
this.isRunning = false
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Process a single item through the full pipeline. */
|
|
158
|
+
private async processItem(item: ProcessingItem): Promise<void> {
|
|
159
|
+
const startTime = Date.now()
|
|
160
|
+
let filePathToSave = item.primaryPath
|
|
161
|
+
|
|
162
|
+
// 1. HDR merge (photos with brackets only)
|
|
163
|
+
if (item.shouldProcess && item.type === "photo" && item.bracketPaths && item.bracketPaths.length >= 3) {
|
|
164
|
+
try {
|
|
165
|
+
const underPath = item.bracketPaths.find((p) => p.includes("ev-2")) || item.bracketPaths[0]
|
|
166
|
+
const normalPath = item.bracketPaths.find((p) => p.includes("ev0")) || item.bracketPaths[1]
|
|
167
|
+
const overPath = item.bracketPaths.find((p) => p.includes("ev2") && !p.includes("ev-2")) || item.bracketPaths[2]
|
|
168
|
+
|
|
169
|
+
const hdrPath = item.primaryPath + ".hdr.jpg"
|
|
170
|
+
const hdrResult = await CrustModule.mergeHdrBrackets(underPath, normalPath, overPath, hdrPath)
|
|
171
|
+
if (hdrResult.success && hdrResult.outputPath) {
|
|
172
|
+
filePathToSave = hdrResult.outputPath
|
|
173
|
+
console.log(`${TAG} HDR merged ${item.id} in ${hdrResult.processingTimeMs}ms`)
|
|
174
|
+
}
|
|
175
|
+
} catch (hdrError) {
|
|
176
|
+
console.warn(`${TAG} HDR merge error for ${item.id}, continuing:`, hdrError)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 2. Image processing (lens + color correction)
|
|
181
|
+
if (item.shouldProcess && item.type === "photo") {
|
|
182
|
+
try {
|
|
183
|
+
const processedPath = filePathToSave + ".processed.jpg"
|
|
184
|
+
const result = await CrustModule.processGalleryImage(filePathToSave, processedPath, {
|
|
185
|
+
lensCorrection: true,
|
|
186
|
+
colorCorrection: true,
|
|
187
|
+
})
|
|
188
|
+
if (result.success && result.outputPath) {
|
|
189
|
+
filePathToSave = result.outputPath
|
|
190
|
+
console.log(`${TAG} 🎨 Processed ${item.id} in ${result.processingTimeMs}ms`)
|
|
191
|
+
}
|
|
192
|
+
} catch (procError) {
|
|
193
|
+
console.warn(`${TAG} Processing error for ${item.id}, using original:`, procError)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// 3. Video stabilization + color correction
|
|
198
|
+
if (item.shouldProcess && item.type === "video" && item.sidecarPath) {
|
|
199
|
+
try {
|
|
200
|
+
const stabilizedPath = item.primaryPath + ".stabilized.mp4"
|
|
201
|
+
const result = await CrustModule.stabilizeVideo(item.primaryPath, item.sidecarPath, stabilizedPath)
|
|
202
|
+
if (result.success && result.outputPath) {
|
|
203
|
+
filePathToSave = result.outputPath
|
|
204
|
+
console.log(`${TAG} 📹 Stabilized ${item.id} in ${result.processingTimeMs}ms`)
|
|
205
|
+
}
|
|
206
|
+
} catch (stabError) {
|
|
207
|
+
console.warn(`${TAG} Stabilization error for ${item.id}, using original:`, stabError)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// 4. Save thumbnail to disk (or use pre-downloaded thumbnail from v1 sync)
|
|
212
|
+
let localThumbnailPath: string | undefined = item.thumbnailPath
|
|
213
|
+
if (item.thumbnailData && item.captureDir) {
|
|
214
|
+
try {
|
|
215
|
+
const thumbPath = `${item.captureDir}/.thumb.jpg`
|
|
216
|
+
const base64Data = item.thumbnailData.startsWith("data:")
|
|
217
|
+
? item.thumbnailData.split(",")[1]
|
|
218
|
+
: item.thumbnailData
|
|
219
|
+
await RNFS.writeFile(thumbPath, base64Data, "base64")
|
|
220
|
+
localThumbnailPath = thumbPath
|
|
221
|
+
} catch (thumbError) {
|
|
222
|
+
console.warn(`${TAG} Failed to save thumbnail for ${item.id}:`, thumbError)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// 5. Validate local file before persisting metadata or deleting from glasses
|
|
227
|
+
try {
|
|
228
|
+
await validateDownloadedMediaFile({
|
|
229
|
+
path: filePathToSave,
|
|
230
|
+
name: item.id,
|
|
231
|
+
mediaKind: item.type,
|
|
232
|
+
})
|
|
233
|
+
} catch (validationError: any) {
|
|
234
|
+
const reason =
|
|
235
|
+
validationError?.message?.includes(INVALID_DOWNLOADED_MEDIA) ?
|
|
236
|
+
validationError.message
|
|
237
|
+
: `${INVALID_DOWNLOADED_MEDIA}: ${item.id}`
|
|
238
|
+
console.error(`${TAG} Validation failed for ${item.id}: ${reason}`)
|
|
239
|
+
reportInvalidGalleryMedia({
|
|
240
|
+
name: item.id,
|
|
241
|
+
path: filePathToSave,
|
|
242
|
+
mediaKind: item.type,
|
|
243
|
+
stage: "processing_validation",
|
|
244
|
+
reason,
|
|
245
|
+
expectedSize: item.totalSize,
|
|
246
|
+
duration: item.duration,
|
|
247
|
+
glassesModel: item.glassesModel,
|
|
248
|
+
})
|
|
249
|
+
const store = useGallerySyncStore.getState()
|
|
250
|
+
store.onFileFailed(item.id, reason)
|
|
251
|
+
await RNFS.unlink(filePathToSave).catch(() => {})
|
|
252
|
+
for (const intermediate of [
|
|
253
|
+
item.primaryPath + ".hdr.jpg",
|
|
254
|
+
item.primaryPath + ".processed.jpg",
|
|
255
|
+
item.primaryPath + ".stabilized.mp4",
|
|
256
|
+
]) {
|
|
257
|
+
if (intermediate !== filePathToSave) {
|
|
258
|
+
await RNFS.unlink(intermediate).catch(() => {})
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
throw new Error(reason)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// 6. Save to camera roll
|
|
265
|
+
if (item.shouldAutoSave) {
|
|
266
|
+
const success = await MediaLibraryPermissions.saveToLibrary(filePathToSave, item.timestamp)
|
|
267
|
+
if (success) {
|
|
268
|
+
console.log(`${TAG} ✅ Saved to camera roll: ${item.id}`)
|
|
269
|
+
} else {
|
|
270
|
+
console.warn(`${TAG} ❌ Failed to save to camera roll: ${item.id}`)
|
|
271
|
+
// D1: Surface camera roll save failures to the UI
|
|
272
|
+
const store = useGallerySyncStore.getState()
|
|
273
|
+
store.onFileFailed(item.id, "camera roll save failed")
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// 7. Save metadata
|
|
278
|
+
const isVideo = item.type === "video"
|
|
279
|
+
const downloadedFile = localStorageService.convertToDownloadedFile(
|
|
280
|
+
{
|
|
281
|
+
name: item.id,
|
|
282
|
+
url: "",
|
|
283
|
+
download: "",
|
|
284
|
+
size: item.totalSize,
|
|
285
|
+
modified: item.timestamp || Date.now(),
|
|
286
|
+
is_video: isVideo,
|
|
287
|
+
thumbnail_data: item.thumbnailData,
|
|
288
|
+
duration: item.duration,
|
|
289
|
+
filePath: filePathToSave,
|
|
290
|
+
glassesModel: item.glassesModel,
|
|
291
|
+
},
|
|
292
|
+
filePathToSave,
|
|
293
|
+
localThumbnailPath,
|
|
294
|
+
item.glassesModel,
|
|
295
|
+
)
|
|
296
|
+
try {
|
|
297
|
+
await localStorageService.saveDownloadedFile(downloadedFile)
|
|
298
|
+
} catch (metadataError) {
|
|
299
|
+
// D2: Clean up orphaned file if metadata save fails, then re-throw
|
|
300
|
+
console.error(`${TAG} Metadata save failed for ${item.id}, cleaning up file:`, metadataError)
|
|
301
|
+
await RNFS.unlink(filePathToSave).catch(() => {})
|
|
302
|
+
throw metadataError
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// S4: Clean up intermediate processing files
|
|
306
|
+
const intermediates = [
|
|
307
|
+
item.primaryPath + ".hdr.jpg",
|
|
308
|
+
item.primaryPath + ".processed.jpg",
|
|
309
|
+
item.primaryPath + ".stabilized.mp4",
|
|
310
|
+
]
|
|
311
|
+
for (const intermediate of intermediates) {
|
|
312
|
+
if (intermediate !== filePathToSave) {
|
|
313
|
+
RNFS.unlink(intermediate).catch(() => {}) // fire-and-forget
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// 8. Update file in sync queue with local paths for gallery display
|
|
318
|
+
const store = useGallerySyncStore.getState()
|
|
319
|
+
const localFileUrl = filePathToSave.startsWith("file://") ? filePathToSave : `file://${filePathToSave}`
|
|
320
|
+
const localThumbUrl = localThumbnailPath
|
|
321
|
+
? localThumbnailPath.startsWith("file://")
|
|
322
|
+
? localThumbnailPath
|
|
323
|
+
: `file://${localThumbnailPath}`
|
|
324
|
+
: undefined
|
|
325
|
+
store.updateFileInQueue(item.id, {
|
|
326
|
+
name: item.id,
|
|
327
|
+
url: localFileUrl,
|
|
328
|
+
download: localFileUrl,
|
|
329
|
+
size: item.totalSize,
|
|
330
|
+
modified: item.timestamp || Date.now(),
|
|
331
|
+
is_video: isVideo,
|
|
332
|
+
filePath: filePathToSave,
|
|
333
|
+
mime_type: isVideo ? "video/mp4" : "image/jpeg",
|
|
334
|
+
thumbnail_data: item.thumbnailData,
|
|
335
|
+
thumbnailPath: localThumbUrl,
|
|
336
|
+
duration: item.duration,
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
// 9. Delete from glasses now that processing is complete — but only if the
|
|
340
|
+
// local file actually exists and has data. If the download was truncated or
|
|
341
|
+
// processing failed silently, we must not destroy the only good copy.
|
|
342
|
+
if (item.deleteFromGlasses && item.deleteFromGlasses.length > 0) {
|
|
343
|
+
try {
|
|
344
|
+
const localFileExists = await RNFS.exists(filePathToSave)
|
|
345
|
+
if (!localFileExists) {
|
|
346
|
+
console.error(`${TAG} Skipping glasses deletion for ${item.id}: local file missing at ${filePathToSave}`)
|
|
347
|
+
} else {
|
|
348
|
+
const localStat = await RNFS.stat(filePathToSave)
|
|
349
|
+
if (localStat.size === 0) {
|
|
350
|
+
console.error(`${TAG} Skipping glasses deletion for ${item.id}: local file is 0 bytes`)
|
|
351
|
+
} else if (item.totalSize > 0 && localStat.size < item.totalSize * 0.5) {
|
|
352
|
+
// If local file is less than 50% of expected size, something went wrong
|
|
353
|
+
console.error(
|
|
354
|
+
`${TAG} Skipping glasses deletion for ${item.id}: local file ${localStat.size} bytes is much smaller than expected ${item.totalSize} bytes`,
|
|
355
|
+
)
|
|
356
|
+
} else {
|
|
357
|
+
await asgCameraApi.deleteFilesFromServer(item.deleteFromGlasses)
|
|
358
|
+
console.log(`${TAG} 🗑️ Deleted ${item.deleteFromGlasses.join(", ")} from glasses`)
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
} catch (deleteError) {
|
|
362
|
+
console.warn(`${TAG} Delete from glasses failed for ${item.id} (non-fatal):`, deleteError)
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const elapsed = Date.now() - startTime
|
|
367
|
+
console.log(`${TAG} ✅ Finished ${item.id} in ${elapsed}ms`)
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export const mediaProcessingQueue = new MediaProcessingQueue()
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {SETTINGS, useSettingsStore} from "../stores/settings"
|
|
2
|
+
|
|
3
|
+
const OTA_VERSION_URL_PROD = "https://ota.mentraglass.com/prod_live_version.json"
|
|
4
|
+
|
|
5
|
+
function isLegacyAsgOtaStartBuild(glassesBuildNumber?: string | null): boolean {
|
|
6
|
+
const buildNumber = Number.parseInt(glassesBuildNumber ?? "", 10)
|
|
7
|
+
// ASG builds before 39 ignore ota_start.ota_version_url, so compare against
|
|
8
|
+
// the URL they will actually use.
|
|
9
|
+
return Number.isFinite(buildNumber) && buildNumber < 39
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function getOtaVersionUrlDevOverride(): string | null {
|
|
13
|
+
// Super mode only: a wrong OTA manifest can brick glasses, so a saved
|
|
14
|
+
// override is inert unless super mode is currently enabled.
|
|
15
|
+
if (!useSettingsStore.getState().getSetting(SETTINGS.super_mode.key)) {
|
|
16
|
+
return null
|
|
17
|
+
}
|
|
18
|
+
const value = useSettingsStore.getState().getSetting(SETTINGS.ota_version_url.key)
|
|
19
|
+
const trimmed = typeof value === "string" ? value.trim() : ""
|
|
20
|
+
return trimmed || null
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getAsgOtaVersionUrl(glassesUrl?: string | null, glassesBuildNumber?: string | null): string {
|
|
24
|
+
const deviceUrl = glassesUrl?.trim()
|
|
25
|
+
if (isLegacyAsgOtaStartBuild(glassesBuildNumber)) {
|
|
26
|
+
// Legacy glasses ignore ota_start.ota_version_url and install from their
|
|
27
|
+
// compiled default, so the developer override does not apply to them either.
|
|
28
|
+
return deviceUrl || OTA_VERSION_URL_PROD
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const devOverrideUrl = getOtaVersionUrlDevOverride()
|
|
32
|
+
if (devOverrideUrl) {
|
|
33
|
+
return devOverrideUrl
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const envUrl = process.env.EXPO_PUBLIC_ASG_OTA_VERSION_URL?.trim()
|
|
37
|
+
if (envUrl) {
|
|
38
|
+
return envUrl
|
|
39
|
+
}
|
|
40
|
+
return deviceUrl || OTA_VERSION_URL_PROD
|
|
41
|
+
}
|
|
@@ -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
|
+
|
|
6
|
+
/** Filesystem-safe path segment. Strips traversal + unsafe chars; never empty. */
|
|
7
|
+
export function sanitizeSegment(s: string): string {
|
|
8
|
+
const cleaned = (s || "").replace(/[^A-Za-z0-9._-]/g, "_")
|
|
9
|
+
if (cleaned === "" || cleaned === "." || cleaned === "..") return "_"
|
|
10
|
+
return cleaned.slice(0, 120)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Filesystem-safe display name for a shared blob, guaranteed to carry an
|
|
15
|
+
* extension. The on-disk blob name is a generated machine id (with a
|
|
16
|
+
* mime-derived extension since withDiskExt; legacy blobs may lack it), so the
|
|
17
|
+
* OS share sheet (which keys off the file path, not any metadata) would
|
|
18
|
+
* otherwise emit a machine-named file — breaking "open with"/preview on the
|
|
19
|
+
* receiving side. Derives the extension from the mimeType when the stored name
|
|
20
|
+
* lacks one.
|
|
21
|
+
*/
|
|
22
|
+
export function shareFileName(meta: {name?: string; fileName: string; mimeType: string}): string {
|
|
23
|
+
const raw = (meta.name || meta.fileName).trim()
|
|
24
|
+
// Replace path separators + characters illegal on common filesystems (keep
|
|
25
|
+
// spaces, hyphens, dots, etc. — they're valid and keep names readable).
|
|
26
|
+
// eslint-disable-next-line no-control-regex
|
|
27
|
+
let safe = raw.replace(/[/\\<>:"|?*\x00-\x1f]/g, "_").trim()
|
|
28
|
+
if (!safe) 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
|
+
/**
|
|
47
|
+
* On-disk name for a stored blob: the generated id plus a mime-derived
|
|
48
|
+
* extension when one is known. iOS AVPlayer resolves a local file's format
|
|
49
|
+
* from its path extension (not content sniffing), so an extension-less WAV is
|
|
50
|
+
* unplayable through `session.speaker.play` even though the bytes are valid.
|
|
51
|
+
* Leaves a name that already has an extension untouched.
|
|
52
|
+
*/
|
|
53
|
+
export function withDiskExt(fileName: string, mimeType: string): string {
|
|
54
|
+
if (fileName.includes(".")) return fileName
|
|
55
|
+
const ext = extForMime(mimeType)
|
|
56
|
+
return ext ? `${fileName}.${ext}` : fileName
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Best-effort file extension (no dot) for a MIME type. Inverse of inferMime in BlobStore. */
|
|
60
|
+
export function extForMime(mime: string): string | undefined {
|
|
61
|
+
const m = (mime || "").split(";")[0].trim().toLowerCase()
|
|
62
|
+
const map: Record<string, string> = {
|
|
63
|
+
"application/pdf": "pdf",
|
|
64
|
+
"application/epub+zip": "epub",
|
|
65
|
+
"application/zip": "zip",
|
|
66
|
+
"application/json": "json",
|
|
67
|
+
"text/plain": "txt",
|
|
68
|
+
"text/csv": "csv",
|
|
69
|
+
"text/html": "html",
|
|
70
|
+
"video/mp4": "mp4",
|
|
71
|
+
"video/quicktime": "mov",
|
|
72
|
+
"video/webm": "webm",
|
|
73
|
+
"audio/mpeg": "mp3",
|
|
74
|
+
"audio/mp4": "m4a",
|
|
75
|
+
"audio/wav": "wav",
|
|
76
|
+
"audio/x-wav": "wav",
|
|
77
|
+
"audio/wave": "wav",
|
|
78
|
+
"audio/ogg": "ogg",
|
|
79
|
+
"image/png": "png",
|
|
80
|
+
"image/jpeg": "jpg",
|
|
81
|
+
"image/gif": "gif",
|
|
82
|
+
"image/webp": "webp",
|
|
83
|
+
"image/svg+xml": "svg",
|
|
84
|
+
}
|
|
85
|
+
return map[m]
|
|
86
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
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
|
+
import {cloudClientService as cloudClient} from "./CloudClientService"
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Restream destination. The full stream key is part of the URL — Cloudflare
|
|
21
|
+
* appends nothing on the publish side. `name` is a human label that surfaces
|
|
22
|
+
* in Cloudflare's dashboard but doesn't affect routing.
|
|
23
|
+
*/
|
|
24
|
+
export interface RestreamDestination {
|
|
25
|
+
url: string
|
|
26
|
+
name?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Caller-facing shape: either a bare URL string or the full object. */
|
|
30
|
+
export type RestreamDestinationInput = string | RestreamDestination
|
|
31
|
+
|
|
32
|
+
export interface ProvisionResult {
|
|
33
|
+
liveInputId: string
|
|
34
|
+
rtmpUrl: string
|
|
35
|
+
srtUrl?: string
|
|
36
|
+
hlsUrl: string
|
|
37
|
+
dashUrl: string
|
|
38
|
+
webrtcUrl?: string
|
|
39
|
+
webrtcPublishUrl?: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CloudflareStatus {
|
|
43
|
+
isConnected: boolean
|
|
44
|
+
state?: string | null
|
|
45
|
+
connectedAt?: string
|
|
46
|
+
lastSeenAt?: string
|
|
47
|
+
reason?: string
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type StreamApiStage = "provision" | "status" | "teardown"
|
|
51
|
+
|
|
52
|
+
export class StreamApiError extends Error {
|
|
53
|
+
readonly transport = "cloud-rest" as const
|
|
54
|
+
constructor(
|
|
55
|
+
public readonly code: string,
|
|
56
|
+
message: string,
|
|
57
|
+
public readonly stage: StreamApiStage,
|
|
58
|
+
) {
|
|
59
|
+
super(message)
|
|
60
|
+
this.name = "StreamApiError"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** The cloud-v2 runtime's ManagedStream wire shape (open records, see protocol). */
|
|
65
|
+
interface ManagedStreamWire {
|
|
66
|
+
streamId: string
|
|
67
|
+
ingest: {
|
|
68
|
+
url?: string
|
|
69
|
+
streamKey?: string
|
|
70
|
+
rtmpUrl?: string
|
|
71
|
+
srtUrl?: string
|
|
72
|
+
webrtcPublishUrl?: string
|
|
73
|
+
}
|
|
74
|
+
playback: {
|
|
75
|
+
hls?: string
|
|
76
|
+
dash?: string
|
|
77
|
+
webrtc?: string
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Provision a managed stream on the cloud-v2 runtime. Returns ready-to-publish
|
|
83
|
+
* ingest URLs (credentials embedded) plus the playback URLs.
|
|
84
|
+
*/
|
|
85
|
+
export async function provisionManagedStream(
|
|
86
|
+
restreamDestinations?: RestreamDestinationInput[],
|
|
87
|
+
): Promise<ProvisionResult> {
|
|
88
|
+
let wire: ManagedStreamWire
|
|
89
|
+
try {
|
|
90
|
+
wire = (await cloudClient.startManagedStream(
|
|
91
|
+
restreamDestinations && restreamDestinations.length > 0 ? {restreamDestinations} : {},
|
|
92
|
+
)) as ManagedStreamWire
|
|
93
|
+
} catch (err) {
|
|
94
|
+
throw new StreamApiError(
|
|
95
|
+
"STREAM_PROVISION_FAILED",
|
|
96
|
+
err instanceof Error ? err.message : String(err),
|
|
97
|
+
"provision",
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const ingest = wire.ingest ?? {}
|
|
102
|
+
const playback = wire.playback ?? {}
|
|
103
|
+
const rtmpUrl = ingest.rtmpUrl ?? (ingest.url && ingest.streamKey ? `${ingest.url}${ingest.streamKey}` : "")
|
|
104
|
+
if (!playback.hls || !playback.dash) {
|
|
105
|
+
throw new StreamApiError(
|
|
106
|
+
"STREAM_PROVISION_INCOMPLETE",
|
|
107
|
+
`runtime returned no playback URLs for stream ${wire.streamId}`,
|
|
108
|
+
"provision",
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
liveInputId: wire.streamId,
|
|
114
|
+
rtmpUrl,
|
|
115
|
+
srtUrl: ingest.srtUrl,
|
|
116
|
+
hlsUrl: playback.hls,
|
|
117
|
+
dashUrl: playback.dash,
|
|
118
|
+
webrtcUrl: playback.webrtc,
|
|
119
|
+
webrtcPublishUrl: ingest.webrtcPublishUrl,
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The provider's view of the ingest: is the device's push arriving? */
|
|
124
|
+
export async function getManagedStreamStatus(liveInputId: string): Promise<CloudflareStatus> {
|
|
125
|
+
try {
|
|
126
|
+
const s = await cloudClient.getManagedStreamStatus(liveInputId)
|
|
127
|
+
return {
|
|
128
|
+
isConnected: s.isConnected,
|
|
129
|
+
state: s.state,
|
|
130
|
+
connectedAt: s.connectedAt,
|
|
131
|
+
lastSeenAt: s.lastSeenAt,
|
|
132
|
+
reason: s.reason,
|
|
133
|
+
}
|
|
134
|
+
} catch (err) {
|
|
135
|
+
throw new StreamApiError(
|
|
136
|
+
"STREAM_STATUS_FAILED",
|
|
137
|
+
err instanceof Error ? err.message : String(err),
|
|
138
|
+
"status",
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Tear down the provider stream. */
|
|
144
|
+
export async function teardownManagedStream(liveInputId: string): Promise<void> {
|
|
145
|
+
try {
|
|
146
|
+
await cloudClient.stopManagedStream(liveInputId)
|
|
147
|
+
} catch (err) {
|
|
148
|
+
throw new StreamApiError(
|
|
149
|
+
"STREAM_TEARDOWN_FAILED",
|
|
150
|
+
err instanceof Error ? err.message : String(err),
|
|
151
|
+
"teardown",
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
|
|
6
|
+
export const CLOCK_SKEW_TOLERANCE_MS = 60_000
|
|
7
|
+
|
|
8
|
+
export type ClockSkewReason = "watermark_ahead_of_glasses" | "wall_clock_drift" | ""
|
|
9
|
+
|
|
10
|
+
export interface ClockSkewResult {
|
|
11
|
+
skewed: boolean
|
|
12
|
+
reason: ClockSkewReason
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function detectClockSkew(
|
|
16
|
+
phoneNow: number,
|
|
17
|
+
glassesServerTime: number,
|
|
18
|
+
lastSyncTime: number,
|
|
19
|
+
toleranceMs: number = CLOCK_SKEW_TOLERANCE_MS,
|
|
20
|
+
): ClockSkewResult {
|
|
21
|
+
if (lastSyncTime > glassesServerTime + toleranceMs) {
|
|
22
|
+
return {skewed: true, reason: "watermark_ahead_of_glasses"}
|
|
23
|
+
}
|
|
24
|
+
if (Math.abs(phoneNow - glassesServerTime) > toleranceMs) {
|
|
25
|
+
return {skewed: true, reason: "wall_clock_drift"}
|
|
26
|
+
}
|
|
27
|
+
return {skewed: false, reason: ""}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isSyncManifestEmpty(syncData: {
|
|
31
|
+
api_version?: number
|
|
32
|
+
captures?: unknown[]
|
|
33
|
+
changed_files?: unknown[]
|
|
34
|
+
}): boolean {
|
|
35
|
+
if (syncData.api_version === 2 && syncData.captures && syncData.captures.length > 0) {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
return !syncData.changed_files || syncData.changed_files.length === 0
|
|
39
|
+
}
|