@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,423 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Storage Service for ASG Gallery
|
|
3
|
+
* Manages downloaded files and sync state
|
|
4
|
+
*/
|
|
5
|
+
import * as RNFS from "@dr.pogodin/react-native-fs";
|
|
6
|
+
import { BgTimer } from "../../utils/timers";
|
|
7
|
+
import { storage, StorageValueNotFoundError } from "../../utils/storage";
|
|
8
|
+
export class LocalStorageService {
|
|
9
|
+
static instance;
|
|
10
|
+
DOWNLOADED_FILES_KEY = "asg_downloaded_files";
|
|
11
|
+
SYNC_STATE_KEY = "asg_sync_state";
|
|
12
|
+
CLIENT_ID_KEY = "asg_client_id";
|
|
13
|
+
SYNC_QUEUE_KEY = "asg_sync_queue";
|
|
14
|
+
ASG_PHOTOS_DIR = `${RNFS.DocumentDirectoryPath}/MentraPhotos`;
|
|
15
|
+
ASG_THUMBNAILS_DIR = `${RNFS.DocumentDirectoryPath}/MentraPhotos/thumbnails`;
|
|
16
|
+
constructor() {
|
|
17
|
+
this.initializeDirectories();
|
|
18
|
+
}
|
|
19
|
+
static getInstance() {
|
|
20
|
+
if (!LocalStorageService.instance) {
|
|
21
|
+
LocalStorageService.instance = new LocalStorageService();
|
|
22
|
+
}
|
|
23
|
+
return LocalStorageService.instance;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Initialize ASG photo directories
|
|
27
|
+
*/
|
|
28
|
+
async initializeDirectories() {
|
|
29
|
+
try {
|
|
30
|
+
// Create main photos directory if it doesn't exist
|
|
31
|
+
const photoDirExists = await RNFS.exists(this.ASG_PHOTOS_DIR);
|
|
32
|
+
if (!photoDirExists) {
|
|
33
|
+
await RNFS.mkdir(this.ASG_PHOTOS_DIR);
|
|
34
|
+
console.log(`[LocalStorage] Created Mentra photos directory: ${this.ASG_PHOTOS_DIR}`);
|
|
35
|
+
}
|
|
36
|
+
// Create thumbnails directory if it doesn't exist
|
|
37
|
+
const thumbDirExists = await RNFS.exists(this.ASG_THUMBNAILS_DIR);
|
|
38
|
+
if (!thumbDirExists) {
|
|
39
|
+
await RNFS.mkdir(this.ASG_THUMBNAILS_DIR);
|
|
40
|
+
console.log(`[LocalStorage] Created Mentra thumbnails directory: ${this.ASG_THUMBNAILS_DIR}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
console.error("[LocalStorage] Error initializing directories:", error);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get the full file path for a photo
|
|
49
|
+
*/
|
|
50
|
+
getPhotoFilePath(filename) {
|
|
51
|
+
return `${this.ASG_PHOTOS_DIR}/${filename}`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the full file path for a thumbnail
|
|
55
|
+
*/
|
|
56
|
+
getThumbnailFilePath(filename) {
|
|
57
|
+
return `${this.ASG_THUMBNAILS_DIR}/${filename}_thumb.jpg`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Initialize client ID if not exists
|
|
61
|
+
*/
|
|
62
|
+
async initializeClientId() {
|
|
63
|
+
let res = storage.load(this.CLIENT_ID_KEY);
|
|
64
|
+
let clientId;
|
|
65
|
+
if (res.is_error()) {
|
|
66
|
+
clientId = `mobile_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
67
|
+
storage.save(this.CLIENT_ID_KEY, clientId);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
clientId = res.value;
|
|
71
|
+
}
|
|
72
|
+
return clientId;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get current sync state
|
|
76
|
+
*/
|
|
77
|
+
async getSyncState() {
|
|
78
|
+
const clientId = await this.initializeClientId();
|
|
79
|
+
const res = storage.load(this.SYNC_STATE_KEY);
|
|
80
|
+
if (res.is_error()) {
|
|
81
|
+
// A missing key is the expected first-sync state (fresh install / never
|
|
82
|
+
// synced) — start from scratch quietly. Real storage failures still log.
|
|
83
|
+
if (!(res.error instanceof StorageValueNotFoundError)) {
|
|
84
|
+
console.error("Error getting sync state:", res.error);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
last_sync_time: 0,
|
|
88
|
+
client_id: clientId,
|
|
89
|
+
total_downloaded: 0,
|
|
90
|
+
total_size: 0,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const syncState = res.value;
|
|
94
|
+
return { ...syncState, client_id: clientId };
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Update sync state
|
|
98
|
+
*/
|
|
99
|
+
async updateSyncState(updates) {
|
|
100
|
+
try {
|
|
101
|
+
const currentState = await this.getSyncState();
|
|
102
|
+
const newState = { ...currentState, ...updates };
|
|
103
|
+
await storage.save(this.SYNC_STATE_KEY, newState);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error("Error updating sync state:", error);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Save downloaded file (only metadata, file should already be written to filesystem)
|
|
112
|
+
*/
|
|
113
|
+
async saveDownloadedFile(file) {
|
|
114
|
+
try {
|
|
115
|
+
const files = await this.getDownloadedFiles();
|
|
116
|
+
// 🔍 DIAGNOSTIC: Check if file already exists
|
|
117
|
+
// const existingFile = files[file.name]
|
|
118
|
+
// if (existingFile) {
|
|
119
|
+
// console.log(`[LocalStorage] ⚠️ WARNING: File ${file.name} ALREADY EXISTS - will be REPLACED!`)
|
|
120
|
+
// console.log(`[LocalStorage] 📁 Existing file:`)
|
|
121
|
+
// console.log(`[LocalStorage] - Downloaded at: ${new Date(existingFile.downloaded_at).toISOString()}`)
|
|
122
|
+
// console.log(`[LocalStorage] - Modified: ${new Date(existingFile.modified).toISOString()}`)
|
|
123
|
+
// console.log(`[LocalStorage] - Size: ${existingFile.size} bytes`)
|
|
124
|
+
// console.log(`[LocalStorage] - Path: ${existingFile.filePath}`)
|
|
125
|
+
// console.log(`[LocalStorage] 📁 New file:`)
|
|
126
|
+
// console.log(`[LocalStorage] - Downloaded at: ${new Date(file.downloaded_at).toISOString()}`)
|
|
127
|
+
// console.log(`[LocalStorage] - Modified: ${new Date(file.modified).toISOString()}`)
|
|
128
|
+
// console.log(`[LocalStorage] - Size: ${file.size} bytes`)
|
|
129
|
+
// console.log(`[LocalStorage] - Path: ${file.filePath}`)
|
|
130
|
+
// console.log(`[LocalStorage] 🔄 This will OVERWRITE the existing entry!`)
|
|
131
|
+
// } else {
|
|
132
|
+
// console.log(`[LocalStorage] ✅ File ${file.name} is NEW - saving metadata`)
|
|
133
|
+
// }
|
|
134
|
+
// Store relative paths to handle iOS app container changes between launches
|
|
135
|
+
// Convert absolute paths to relative (remove DocumentDirectoryPath prefix)
|
|
136
|
+
const docPath = RNFS.DocumentDirectoryPath;
|
|
137
|
+
const relativePath = file.filePath.startsWith(docPath)
|
|
138
|
+
? file.filePath.substring(docPath.length + 1) // +1 for the slash
|
|
139
|
+
: file.filePath;
|
|
140
|
+
const relativeThumbnailPath = file.thumbnailPath
|
|
141
|
+
? file.thumbnailPath.startsWith(docPath)
|
|
142
|
+
? file.thumbnailPath.substring(docPath.length + 1)
|
|
143
|
+
: file.thumbnailPath
|
|
144
|
+
: undefined;
|
|
145
|
+
files[file.name] = {
|
|
146
|
+
...file,
|
|
147
|
+
// Store relative paths instead of absolute
|
|
148
|
+
filePath: relativePath,
|
|
149
|
+
thumbnailPath: relativeThumbnailPath,
|
|
150
|
+
};
|
|
151
|
+
await storage.save(this.DOWNLOADED_FILES_KEY, files);
|
|
152
|
+
// console.log(`[LocalStorage] 💾 Saved metadata for ${file.name} with relative path: ${relativePath}`)
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
console.error("Error saving downloaded file metadata:", error);
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get all downloaded files
|
|
161
|
+
*/
|
|
162
|
+
async getDownloadedFiles() {
|
|
163
|
+
const res = storage.load(this.DOWNLOADED_FILES_KEY);
|
|
164
|
+
if (res.is_error()) {
|
|
165
|
+
// Not an error - just means no files have been downloaded yet (first use)
|
|
166
|
+
// Only log as debug, not error, since this is expected on first launch
|
|
167
|
+
console.log("[LocalStorage] No downloaded files found (first use or empty gallery)");
|
|
168
|
+
return {};
|
|
169
|
+
}
|
|
170
|
+
const files = res.value;
|
|
171
|
+
const reconstructedFiles = {};
|
|
172
|
+
const docPath = RNFS.DocumentDirectoryPath;
|
|
173
|
+
// Reconstruct absolute paths from relative paths
|
|
174
|
+
for (const [name, file] of Object.entries(files)) {
|
|
175
|
+
// Check if path is already absolute (legacy data) or relative
|
|
176
|
+
const absolutePath = file.filePath.startsWith("/")
|
|
177
|
+
? file.filePath // Already absolute (legacy data)
|
|
178
|
+
: `${docPath}/${file.filePath}`; // Relative path, prepend DocumentDirectoryPath
|
|
179
|
+
const absoluteThumbnailPath = file.thumbnailPath
|
|
180
|
+
? file.thumbnailPath.startsWith("/")
|
|
181
|
+
? file.thumbnailPath // Already absolute (legacy data)
|
|
182
|
+
: `${docPath}/${file.thumbnailPath}` // Relative path
|
|
183
|
+
: undefined;
|
|
184
|
+
reconstructedFiles[name] = {
|
|
185
|
+
...file,
|
|
186
|
+
filePath: absolutePath,
|
|
187
|
+
thumbnailPath: absoluteThumbnailPath,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return reconstructedFiles;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Get downloaded file by name
|
|
194
|
+
*/
|
|
195
|
+
async getDownloadedFile(fileName) {
|
|
196
|
+
try {
|
|
197
|
+
const files = await this.getDownloadedFiles();
|
|
198
|
+
return files[fileName] || null;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error("Error getting downloaded file:", error);
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Delete downloaded file (both metadata and actual files)
|
|
207
|
+
*/
|
|
208
|
+
async deleteDownloadedFile(fileName) {
|
|
209
|
+
try {
|
|
210
|
+
const files = await this.getDownloadedFiles();
|
|
211
|
+
if (files[fileName]) {
|
|
212
|
+
const file = files[fileName];
|
|
213
|
+
// Delete actual file from filesystem
|
|
214
|
+
if (file.filePath && (await RNFS.exists(file.filePath))) {
|
|
215
|
+
await RNFS.unlink(file.filePath);
|
|
216
|
+
console.log(`[LocalStorage] Deleted file: ${file.filePath}`);
|
|
217
|
+
}
|
|
218
|
+
// Delete thumbnail if exists
|
|
219
|
+
if (file.thumbnailPath && (await RNFS.exists(file.thumbnailPath))) {
|
|
220
|
+
await RNFS.unlink(file.thumbnailPath);
|
|
221
|
+
console.log(`[LocalStorage] Deleted thumbnail: ${file.thumbnailPath}`);
|
|
222
|
+
}
|
|
223
|
+
// Delete metadata - need to get raw data to maintain relative paths
|
|
224
|
+
const res = storage.load(this.DOWNLOADED_FILES_KEY);
|
|
225
|
+
if (res.is_error()) {
|
|
226
|
+
console.error("Error loading downloaded files:", res.error);
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
const rawFiles = res.value;
|
|
230
|
+
delete rawFiles[fileName];
|
|
231
|
+
await storage.save(this.DOWNLOADED_FILES_KEY, rawFiles);
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
console.error("Error deleting downloaded file:", error);
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Convert PhotoInfo to DownloadedFile (assumes files are already saved to filesystem)
|
|
243
|
+
*/
|
|
244
|
+
convertToDownloadedFile(photoInfo, filePath, thumbnailPath, glassesModel) {
|
|
245
|
+
return {
|
|
246
|
+
name: photoInfo.name,
|
|
247
|
+
filePath: filePath,
|
|
248
|
+
size: photoInfo.size,
|
|
249
|
+
modified: new Date(photoInfo.modified).getTime(),
|
|
250
|
+
mime_type: photoInfo.mime_type || (photoInfo.is_video ? "video/mp4" : "image/jpeg"),
|
|
251
|
+
is_video: photoInfo.is_video || false,
|
|
252
|
+
thumbnailPath: thumbnailPath,
|
|
253
|
+
downloaded_at: Date.now(),
|
|
254
|
+
glassesModel: glassesModel || photoInfo.glassesModel,
|
|
255
|
+
duration: photoInfo.duration,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Convert DownloadedFile to PhotoInfo
|
|
260
|
+
*/
|
|
261
|
+
convertToPhotoInfo(downloadedFile) {
|
|
262
|
+
// Use file:// URLs for local files
|
|
263
|
+
// On iOS, ensure we have proper file:// URL format with correct number of slashes
|
|
264
|
+
const fileUrl = downloadedFile.filePath.startsWith("file://")
|
|
265
|
+
? downloadedFile.filePath
|
|
266
|
+
: downloadedFile.filePath.startsWith("/")
|
|
267
|
+
? `file://${downloadedFile.filePath}` // Path already has leading slash
|
|
268
|
+
: `file:///${downloadedFile.filePath}`; // Path needs leading slash
|
|
269
|
+
const thumbnailUrl = downloadedFile.thumbnailPath
|
|
270
|
+
? downloadedFile.thumbnailPath.startsWith("file://")
|
|
271
|
+
? downloadedFile.thumbnailPath
|
|
272
|
+
: downloadedFile.thumbnailPath.startsWith("/")
|
|
273
|
+
? `file://${downloadedFile.thumbnailPath}` // Path already has leading slash
|
|
274
|
+
: `file:///${downloadedFile.thumbnailPath}` // Path needs leading slash
|
|
275
|
+
: undefined;
|
|
276
|
+
return {
|
|
277
|
+
name: downloadedFile.name,
|
|
278
|
+
url: fileUrl,
|
|
279
|
+
download: fileUrl,
|
|
280
|
+
size: downloadedFile.size,
|
|
281
|
+
modified: new Date(downloadedFile.modified).toISOString(),
|
|
282
|
+
mime_type: downloadedFile.mime_type,
|
|
283
|
+
is_video: downloadedFile.is_video,
|
|
284
|
+
thumbnail_data: undefined,
|
|
285
|
+
downloaded_at: downloadedFile.downloaded_at,
|
|
286
|
+
filePath: downloadedFile.filePath,
|
|
287
|
+
glassesModel: downloadedFile.glassesModel,
|
|
288
|
+
thumbnailPath: thumbnailUrl, // Use the file:// URL version for thumbnailPath
|
|
289
|
+
duration: downloadedFile.duration,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get storage statistics
|
|
294
|
+
*/
|
|
295
|
+
async getStorageStats() {
|
|
296
|
+
try {
|
|
297
|
+
const files = await this.getDownloadedFiles();
|
|
298
|
+
const syncState = await this.getSyncState();
|
|
299
|
+
const totalSize = Object.values(files).reduce((sum, file) => sum + file.size, 0);
|
|
300
|
+
return {
|
|
301
|
+
total_files: Object.keys(files).length,
|
|
302
|
+
total_size: totalSize,
|
|
303
|
+
last_sync: syncState.last_sync_time,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
console.error("Error getting storage stats:", error);
|
|
308
|
+
return {
|
|
309
|
+
total_files: 0,
|
|
310
|
+
total_size: 0,
|
|
311
|
+
last_sync: 0,
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Clear all downloaded files (both metadata and actual files)
|
|
317
|
+
*/
|
|
318
|
+
async clearAllFiles() {
|
|
319
|
+
// Nuke the entire photos directory (includes thumbnails subdirectory)
|
|
320
|
+
// This is more reliable than deleting individual files, which can miss orphaned thumbnails
|
|
321
|
+
try {
|
|
322
|
+
if (await RNFS.exists(this.ASG_PHOTOS_DIR)) {
|
|
323
|
+
await RNFS.unlink(this.ASG_PHOTOS_DIR);
|
|
324
|
+
console.log("[LocalStorage] Deleted entire photos directory");
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
console.error("[LocalStorage] Error deleting photos directory:", error);
|
|
329
|
+
}
|
|
330
|
+
// Recreate empty directories
|
|
331
|
+
await this.initializeDirectories();
|
|
332
|
+
// Clear metadata
|
|
333
|
+
const res = await storage.remove(this.DOWNLOADED_FILES_KEY);
|
|
334
|
+
if (res.is_error()) {
|
|
335
|
+
console.error("[LocalStorage] Error clearing downloaded files:", res.error);
|
|
336
|
+
throw res.error;
|
|
337
|
+
}
|
|
338
|
+
console.log("[LocalStorage] Cleared all downloaded files and thumbnails");
|
|
339
|
+
}
|
|
340
|
+
// ============================================
|
|
341
|
+
// Sync Queue Persistence (for background sync resume)
|
|
342
|
+
// ============================================
|
|
343
|
+
/**
|
|
344
|
+
* Save sync queue for potential resume after app restart
|
|
345
|
+
*/
|
|
346
|
+
async saveSyncQueue(queue) {
|
|
347
|
+
try {
|
|
348
|
+
await storage.save(this.SYNC_QUEUE_KEY, queue);
|
|
349
|
+
console.log(`[LocalStorage] Saved sync queue: ${queue.files.length} files, index ${queue.currentIndex}`);
|
|
350
|
+
}
|
|
351
|
+
catch (error) {
|
|
352
|
+
console.error("[LocalStorage] Error saving sync queue:", error);
|
|
353
|
+
throw error;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Get saved sync queue (for resume on app restart)
|
|
358
|
+
*/
|
|
359
|
+
async getSyncQueue() {
|
|
360
|
+
try {
|
|
361
|
+
const res = storage.load(this.SYNC_QUEUE_KEY);
|
|
362
|
+
if (res.is_error()) {
|
|
363
|
+
// No queue saved - this is normal
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
const queue = res.value;
|
|
367
|
+
console.log(`[LocalStorage] Loaded sync queue: ${queue.files.length} files, index ${queue.currentIndex}`);
|
|
368
|
+
return queue;
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
console.error("[LocalStorage] Error loading sync queue:", error);
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Update the current index of the sync queue (called after each file completes)
|
|
377
|
+
*/
|
|
378
|
+
async updateSyncQueueIndex(newIndex) {
|
|
379
|
+
// S6: Let errors propagate — caller uses .catch() for non-critical updates
|
|
380
|
+
const queue = await this.getSyncQueue();
|
|
381
|
+
if (queue) {
|
|
382
|
+
queue.currentIndex = newIndex;
|
|
383
|
+
await this.saveSyncQueue(queue);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Clear sync queue (called on sync complete or cancel)
|
|
388
|
+
*/
|
|
389
|
+
async clearSyncQueue() {
|
|
390
|
+
// S6: Retry up to 3 times to ensure queue is cleared
|
|
391
|
+
for (let attempt = 1; attempt <= 3; attempt++) {
|
|
392
|
+
try {
|
|
393
|
+
const res = await storage.remove(this.SYNC_QUEUE_KEY);
|
|
394
|
+
if (res.is_error()) {
|
|
395
|
+
console.error(`[LocalStorage] Error clearing sync queue (attempt ${attempt}/3):`, res.error);
|
|
396
|
+
if (attempt < 3)
|
|
397
|
+
continue;
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
console.log("[LocalStorage] Cleared sync queue");
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
console.error(`[LocalStorage] Error clearing sync queue (attempt ${attempt}/3):`, error);
|
|
405
|
+
if (attempt < 3) {
|
|
406
|
+
await new Promise((resolve) => BgTimer.setTimeout(() => resolve(), 100));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Check if there's a resumable sync queue
|
|
413
|
+
*/
|
|
414
|
+
async hasResumableSyncQueue() {
|
|
415
|
+
const queue = await this.getSyncQueue();
|
|
416
|
+
if (!queue)
|
|
417
|
+
return false;
|
|
418
|
+
// Has resumable queue if there are still files to process
|
|
419
|
+
return queue.currentIndex < queue.files.length;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
export const localStorageService = LocalStorageService.getInstance();
|
|
423
|
+
//# sourceMappingURL=localStorageService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localStorageService.js","sourceRoot":"","sources":["../../../src/services/asg/localStorageService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Local Storage Service for ASG Gallery\n * Manages downloaded files and sync state\n */\n\nimport * as RNFS from \"@dr.pogodin/react-native-fs\"\n\nimport {PhotoInfo} from \"../../types/asg\"\nimport {BgTimer} from \"../../utils/timers\"\nimport {storage, StorageValueNotFoundError} from \"../../utils/storage\"\n\nexport interface DownloadedFile {\n name: string\n filePath: string // Path to file on filesystem\n size: number\n modified: number\n mime_type: string\n is_video: boolean\n thumbnailPath?: string // Path to thumbnail file\n downloaded_at: number\n glassesModel?: string // Model of glasses that captured this media\n duration?: number // Video duration in milliseconds\n capture_id?: string // Capture folder name (when synced via capture-aware pipeline)\n}\n\ninterface SyncState {\n last_sync_time: number\n client_id: string\n total_downloaded: number\n total_size: number\n}\n\nexport interface SyncQueueData {\n files: PhotoInfo[]\n currentIndex: number\n startedAt: number\n hotspotInfo: {\n ssid: string\n password: string\n ip: string\n }\n}\n\nexport class LocalStorageService {\n private static instance: LocalStorageService\n private readonly DOWNLOADED_FILES_KEY = \"asg_downloaded_files\"\n private readonly SYNC_STATE_KEY = \"asg_sync_state\"\n private readonly CLIENT_ID_KEY = \"asg_client_id\"\n private readonly SYNC_QUEUE_KEY = \"asg_sync_queue\"\n private readonly ASG_PHOTOS_DIR = `${RNFS.DocumentDirectoryPath}/MentraPhotos`\n private readonly ASG_THUMBNAILS_DIR = `${RNFS.DocumentDirectoryPath}/MentraPhotos/thumbnails`\n\n private constructor() {\n this.initializeDirectories()\n }\n\n static getInstance(): LocalStorageService {\n if (!LocalStorageService.instance) {\n LocalStorageService.instance = new LocalStorageService()\n }\n return LocalStorageService.instance\n }\n\n /**\n * Initialize ASG photo directories\n */\n private async initializeDirectories(): Promise<void> {\n try {\n // Create main photos directory if it doesn't exist\n const photoDirExists = await RNFS.exists(this.ASG_PHOTOS_DIR)\n if (!photoDirExists) {\n await RNFS.mkdir(this.ASG_PHOTOS_DIR)\n console.log(`[LocalStorage] Created Mentra photos directory: ${this.ASG_PHOTOS_DIR}`)\n }\n\n // Create thumbnails directory if it doesn't exist\n const thumbDirExists = await RNFS.exists(this.ASG_THUMBNAILS_DIR)\n if (!thumbDirExists) {\n await RNFS.mkdir(this.ASG_THUMBNAILS_DIR)\n console.log(`[LocalStorage] Created Mentra thumbnails directory: ${this.ASG_THUMBNAILS_DIR}`)\n }\n } catch (error) {\n console.error(\"[LocalStorage] Error initializing directories:\", error)\n }\n }\n\n /**\n * Get the full file path for a photo\n */\n getPhotoFilePath(filename: string): string {\n return `${this.ASG_PHOTOS_DIR}/${filename}`\n }\n\n /**\n * Get the full file path for a thumbnail\n */\n getThumbnailFilePath(filename: string): string {\n return `${this.ASG_THUMBNAILS_DIR}/${filename}_thumb.jpg`\n }\n\n /**\n * Initialize client ID if not exists\n */\n async initializeClientId(): Promise<string> {\n let res = storage.load<string>(this.CLIENT_ID_KEY)\n let clientId\n if (res.is_error()) {\n clientId = `mobile_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`\n storage.save(this.CLIENT_ID_KEY, clientId)\n } else {\n clientId = res.value\n }\n return clientId\n }\n\n /**\n * Get current sync state\n */\n async getSyncState(): Promise<SyncState> {\n const clientId = await this.initializeClientId()\n const res = storage.load<SyncState>(this.SYNC_STATE_KEY)\n\n if (res.is_error()) {\n // A missing key is the expected first-sync state (fresh install / never\n // synced) — start from scratch quietly. Real storage failures still log.\n if (!(res.error instanceof StorageValueNotFoundError)) {\n console.error(\"Error getting sync state:\", res.error)\n }\n return {\n last_sync_time: 0,\n client_id: clientId,\n total_downloaded: 0,\n total_size: 0,\n }\n }\n\n const syncState = res.value\n return {...syncState, client_id: clientId}\n }\n\n /**\n * Update sync state\n */\n async updateSyncState(updates: Partial<SyncState>): Promise<void> {\n try {\n const currentState = await this.getSyncState()\n const newState = {...currentState, ...updates}\n await storage.save(this.SYNC_STATE_KEY, newState)\n } catch (error) {\n console.error(\"Error updating sync state:\", error)\n throw error\n }\n }\n\n /**\n * Save downloaded file (only metadata, file should already be written to filesystem)\n */\n async saveDownloadedFile(file: DownloadedFile): Promise<void> {\n try {\n const files = await this.getDownloadedFiles()\n\n // 🔍 DIAGNOSTIC: Check if file already exists\n // const existingFile = files[file.name]\n // if (existingFile) {\n // console.log(`[LocalStorage] ⚠️ WARNING: File ${file.name} ALREADY EXISTS - will be REPLACED!`)\n // console.log(`[LocalStorage] 📁 Existing file:`)\n // console.log(`[LocalStorage] - Downloaded at: ${new Date(existingFile.downloaded_at).toISOString()}`)\n // console.log(`[LocalStorage] - Modified: ${new Date(existingFile.modified).toISOString()}`)\n // console.log(`[LocalStorage] - Size: ${existingFile.size} bytes`)\n // console.log(`[LocalStorage] - Path: ${existingFile.filePath}`)\n // console.log(`[LocalStorage] 📁 New file:`)\n // console.log(`[LocalStorage] - Downloaded at: ${new Date(file.downloaded_at).toISOString()}`)\n // console.log(`[LocalStorage] - Modified: ${new Date(file.modified).toISOString()}`)\n // console.log(`[LocalStorage] - Size: ${file.size} bytes`)\n // console.log(`[LocalStorage] - Path: ${file.filePath}`)\n // console.log(`[LocalStorage] 🔄 This will OVERWRITE the existing entry!`)\n // } else {\n // console.log(`[LocalStorage] ✅ File ${file.name} is NEW - saving metadata`)\n // }\n\n // Store relative paths to handle iOS app container changes between launches\n // Convert absolute paths to relative (remove DocumentDirectoryPath prefix)\n const docPath = RNFS.DocumentDirectoryPath\n const relativePath = file.filePath.startsWith(docPath)\n ? file.filePath.substring(docPath.length + 1) // +1 for the slash\n : file.filePath\n const relativeThumbnailPath = file.thumbnailPath\n ? file.thumbnailPath.startsWith(docPath)\n ? file.thumbnailPath.substring(docPath.length + 1)\n : file.thumbnailPath\n : undefined\n\n files[file.name] = {\n ...file,\n // Store relative paths instead of absolute\n filePath: relativePath,\n thumbnailPath: relativeThumbnailPath,\n }\n await storage.save(this.DOWNLOADED_FILES_KEY, files)\n // console.log(`[LocalStorage] 💾 Saved metadata for ${file.name} with relative path: ${relativePath}`)\n } catch (error) {\n console.error(\"Error saving downloaded file metadata:\", error)\n throw error\n }\n }\n\n /**\n * Get all downloaded files\n */\n async getDownloadedFiles(): Promise<Record<string, DownloadedFile>> {\n const res = storage.load<Record<string, DownloadedFile>>(this.DOWNLOADED_FILES_KEY)\n if (res.is_error()) {\n // Not an error - just means no files have been downloaded yet (first use)\n // Only log as debug, not error, since this is expected on first launch\n console.log(\"[LocalStorage] No downloaded files found (first use or empty gallery)\")\n return {}\n }\n\n const files = res.value\n const reconstructedFiles: Record<string, DownloadedFile> = {}\n const docPath = RNFS.DocumentDirectoryPath\n\n // Reconstruct absolute paths from relative paths\n for (const [name, file] of Object.entries(files as Record<string, DownloadedFile>)) {\n // Check if path is already absolute (legacy data) or relative\n const absolutePath = file.filePath.startsWith(\"/\")\n ? file.filePath // Already absolute (legacy data)\n : `${docPath}/${file.filePath}` // Relative path, prepend DocumentDirectoryPath\n\n const absoluteThumbnailPath = file.thumbnailPath\n ? file.thumbnailPath.startsWith(\"/\")\n ? file.thumbnailPath // Already absolute (legacy data)\n : `${docPath}/${file.thumbnailPath}` // Relative path\n : undefined\n\n reconstructedFiles[name] = {\n ...file,\n filePath: absolutePath,\n thumbnailPath: absoluteThumbnailPath,\n }\n }\n\n return reconstructedFiles\n }\n\n /**\n * Get downloaded file by name\n */\n async getDownloadedFile(fileName: string): Promise<DownloadedFile | null> {\n try {\n const files = await this.getDownloadedFiles()\n return files[fileName] || null\n } catch (error) {\n console.error(\"Error getting downloaded file:\", error)\n return null\n }\n }\n\n /**\n * Delete downloaded file (both metadata and actual files)\n */\n async deleteDownloadedFile(fileName: string): Promise<boolean> {\n try {\n const files = await this.getDownloadedFiles()\n if (files[fileName]) {\n const file = files[fileName]\n\n // Delete actual file from filesystem\n if (file.filePath && (await RNFS.exists(file.filePath))) {\n await RNFS.unlink(file.filePath)\n console.log(`[LocalStorage] Deleted file: ${file.filePath}`)\n }\n\n // Delete thumbnail if exists\n if (file.thumbnailPath && (await RNFS.exists(file.thumbnailPath))) {\n await RNFS.unlink(file.thumbnailPath)\n console.log(`[LocalStorage] Deleted thumbnail: ${file.thumbnailPath}`)\n }\n\n // Delete metadata - need to get raw data to maintain relative paths\n const res = storage.load<Record<string, DownloadedFile>>(this.DOWNLOADED_FILES_KEY)\n if (res.is_error()) {\n console.error(\"Error loading downloaded files:\", res.error)\n return false\n }\n const rawFiles = res.value\n delete rawFiles[fileName]\n await storage.save(this.DOWNLOADED_FILES_KEY, rawFiles)\n return true\n }\n return false\n } catch (error) {\n console.error(\"Error deleting downloaded file:\", error)\n return false\n }\n }\n\n /**\n * Convert PhotoInfo to DownloadedFile (assumes files are already saved to filesystem)\n */\n convertToDownloadedFile(\n photoInfo: PhotoInfo,\n filePath: string,\n thumbnailPath?: string,\n glassesModel?: string,\n ): DownloadedFile {\n return {\n name: photoInfo.name,\n filePath: filePath,\n size: photoInfo.size,\n modified: new Date(photoInfo.modified).getTime(),\n mime_type: photoInfo.mime_type || (photoInfo.is_video ? \"video/mp4\" : \"image/jpeg\"),\n is_video: photoInfo.is_video || false,\n thumbnailPath: thumbnailPath,\n downloaded_at: Date.now(),\n glassesModel: glassesModel || photoInfo.glassesModel,\n duration: photoInfo.duration,\n }\n }\n\n /**\n * Convert DownloadedFile to PhotoInfo\n */\n convertToPhotoInfo(downloadedFile: DownloadedFile): PhotoInfo {\n // Use file:// URLs for local files\n // On iOS, ensure we have proper file:// URL format with correct number of slashes\n const fileUrl = downloadedFile.filePath.startsWith(\"file://\")\n ? downloadedFile.filePath\n : downloadedFile.filePath.startsWith(\"/\")\n ? `file://${downloadedFile.filePath}` // Path already has leading slash\n : `file:///${downloadedFile.filePath}` // Path needs leading slash\n\n const thumbnailUrl = downloadedFile.thumbnailPath\n ? downloadedFile.thumbnailPath.startsWith(\"file://\")\n ? downloadedFile.thumbnailPath\n : downloadedFile.thumbnailPath.startsWith(\"/\")\n ? `file://${downloadedFile.thumbnailPath}` // Path already has leading slash\n : `file:///${downloadedFile.thumbnailPath}` // Path needs leading slash\n : undefined\n\n return {\n name: downloadedFile.name,\n url: fileUrl,\n download: fileUrl,\n size: downloadedFile.size,\n modified: new Date(downloadedFile.modified).toISOString(),\n mime_type: downloadedFile.mime_type,\n is_video: downloadedFile.is_video,\n thumbnail_data: undefined,\n downloaded_at: downloadedFile.downloaded_at,\n filePath: downloadedFile.filePath,\n glassesModel: downloadedFile.glassesModel,\n thumbnailPath: thumbnailUrl, // Use the file:// URL version for thumbnailPath\n duration: downloadedFile.duration,\n }\n }\n\n /**\n * Get storage statistics\n */\n async getStorageStats(): Promise<{\n total_files: number\n total_size: number\n last_sync: number\n }> {\n try {\n const files = await this.getDownloadedFiles()\n const syncState = await this.getSyncState()\n\n const totalSize = Object.values(files).reduce((sum, file) => sum + file.size, 0)\n\n return {\n total_files: Object.keys(files).length,\n total_size: totalSize,\n last_sync: syncState.last_sync_time,\n }\n } catch (error) {\n console.error(\"Error getting storage stats:\", error)\n return {\n total_files: 0,\n total_size: 0,\n last_sync: 0,\n }\n }\n }\n\n /**\n * Clear all downloaded files (both metadata and actual files)\n */\n async clearAllFiles(): Promise<void> {\n // Nuke the entire photos directory (includes thumbnails subdirectory)\n // This is more reliable than deleting individual files, which can miss orphaned thumbnails\n try {\n if (await RNFS.exists(this.ASG_PHOTOS_DIR)) {\n await RNFS.unlink(this.ASG_PHOTOS_DIR)\n console.log(\"[LocalStorage] Deleted entire photos directory\")\n }\n } catch (error) {\n console.error(\"[LocalStorage] Error deleting photos directory:\", error)\n }\n\n // Recreate empty directories\n await this.initializeDirectories()\n\n // Clear metadata\n const res = await storage.remove(this.DOWNLOADED_FILES_KEY)\n if (res.is_error()) {\n console.error(\"[LocalStorage] Error clearing downloaded files:\", res.error)\n throw res.error\n }\n console.log(\"[LocalStorage] Cleared all downloaded files and thumbnails\")\n }\n\n // ============================================\n // Sync Queue Persistence (for background sync resume)\n // ============================================\n\n /**\n * Save sync queue for potential resume after app restart\n */\n async saveSyncQueue(queue: SyncQueueData): Promise<void> {\n try {\n await storage.save(this.SYNC_QUEUE_KEY, queue)\n console.log(`[LocalStorage] Saved sync queue: ${queue.files.length} files, index ${queue.currentIndex}`)\n } catch (error) {\n console.error(\"[LocalStorage] Error saving sync queue:\", error)\n throw error\n }\n }\n\n /**\n * Get saved sync queue (for resume on app restart)\n */\n async getSyncQueue(): Promise<SyncQueueData | null> {\n try {\n const res = storage.load<SyncQueueData>(this.SYNC_QUEUE_KEY)\n if (res.is_error()) {\n // No queue saved - this is normal\n return null\n }\n const queue = res.value\n console.log(`[LocalStorage] Loaded sync queue: ${queue.files.length} files, index ${queue.currentIndex}`)\n return queue\n } catch (error) {\n console.error(\"[LocalStorage] Error loading sync queue:\", error)\n return null\n }\n }\n\n /**\n * Update the current index of the sync queue (called after each file completes)\n */\n async updateSyncQueueIndex(newIndex: number): Promise<void> {\n // S6: Let errors propagate — caller uses .catch() for non-critical updates\n const queue = await this.getSyncQueue()\n if (queue) {\n queue.currentIndex = newIndex\n await this.saveSyncQueue(queue)\n }\n }\n\n /**\n * Clear sync queue (called on sync complete or cancel)\n */\n async clearSyncQueue(): Promise<void> {\n // S6: Retry up to 3 times to ensure queue is cleared\n for (let attempt = 1; attempt <= 3; attempt++) {\n try {\n const res = await storage.remove(this.SYNC_QUEUE_KEY)\n if (res.is_error()) {\n console.error(`[LocalStorage] Error clearing sync queue (attempt ${attempt}/3):`, res.error)\n if (attempt < 3) continue\n return\n }\n console.log(\"[LocalStorage] Cleared sync queue\")\n return\n } catch (error) {\n console.error(`[LocalStorage] Error clearing sync queue (attempt ${attempt}/3):`, error)\n if (attempt < 3) {\n await new Promise<void>((resolve) => BgTimer.setTimeout(() => resolve(), 100))\n }\n }\n }\n }\n\n /**\n * Check if there's a resumable sync queue\n */\n async hasResumableSyncQueue(): Promise<boolean> {\n const queue = await this.getSyncQueue()\n if (!queue) return false\n // Has resumable queue if there are still files to process\n return queue.currentIndex < queue.files.length\n }\n}\n\nexport const localStorageService = LocalStorageService.getInstance()\n"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
export interface ProcessingItem {
|
|
8
|
+
/** Unique ID — capture_id (v2) or file name (v1) */
|
|
9
|
+
id: string;
|
|
10
|
+
type: "photo" | "video";
|
|
11
|
+
/** Path to the primary downloaded file */
|
|
12
|
+
primaryPath: string;
|
|
13
|
+
/** HDR bracket paths (v2 only) */
|
|
14
|
+
bracketPaths?: string[];
|
|
15
|
+
/** IMU sidecar path for video stabilization */
|
|
16
|
+
sidecarPath?: string;
|
|
17
|
+
/** Thumbnail base64 data */
|
|
18
|
+
thumbnailData?: string;
|
|
19
|
+
/** Capture directory for saving thumbnail */
|
|
20
|
+
captureDir?: string;
|
|
21
|
+
/** Original capture timestamp */
|
|
22
|
+
timestamp?: number;
|
|
23
|
+
/** Total file size */
|
|
24
|
+
totalSize: number;
|
|
25
|
+
/** Video duration in ms */
|
|
26
|
+
duration?: number;
|
|
27
|
+
/** Glasses model */
|
|
28
|
+
glassesModel?: string;
|
|
29
|
+
/** Whether to process (lens/color/stabilization) */
|
|
30
|
+
shouldProcess: boolean;
|
|
31
|
+
/** Whether to auto-save to camera roll */
|
|
32
|
+
shouldAutoSave: boolean;
|
|
33
|
+
/** Pre-downloaded thumbnail path (v1 legacy sync) */
|
|
34
|
+
thumbnailPath?: string;
|
|
35
|
+
/** File names to delete from glasses after processing completes */
|
|
36
|
+
deleteFromGlasses?: string[];
|
|
37
|
+
}
|
|
38
|
+
declare class MediaProcessingQueue {
|
|
39
|
+
private queue;
|
|
40
|
+
private isRunning;
|
|
41
|
+
private aborted;
|
|
42
|
+
private generation;
|
|
43
|
+
/** Add an item to the processing queue. Starts processing if not already running. */
|
|
44
|
+
enqueue(item: ProcessingItem): void;
|
|
45
|
+
/** Cancel all pending processing. */
|
|
46
|
+
abort(): void;
|
|
47
|
+
/** Reset state for a new sync session. */
|
|
48
|
+
reset(): void;
|
|
49
|
+
/** Returns true if there are items queued or currently processing. */
|
|
50
|
+
get hasPending(): boolean;
|
|
51
|
+
/** Returns a promise that resolves when the queue is fully drained, or rejects on timeout. */
|
|
52
|
+
waitUntilDrained(timeoutMs?: number): Promise<void>;
|
|
53
|
+
/** Process items one at a time. */
|
|
54
|
+
private processLoop;
|
|
55
|
+
/** Process a single item through the full pipeline. */
|
|
56
|
+
private processItem;
|
|
57
|
+
}
|
|
58
|
+
export declare const mediaProcessingQueue: MediaProcessingQueue;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=mediaProcessingQueue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mediaProcessingQueue.d.ts","sourceRoot":"","sources":["../../../src/services/asg/mediaProcessingQueue.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,kCAAkC;IAClC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,oDAAoD;IACpD,aAAa,EAAE,OAAO,CAAA;IACtB,0CAA0C;IAC1C,cAAc,EAAE,OAAO,CAAA;IACvB,qDAAqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC7B;AAED,cAAM,oBAAoB;IACxB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,UAAU,CAAI;IAEtB,qFAAqF;IACrF,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI;IAenC,qCAAqC;IACrC,KAAK,IAAI,IAAI;IAMb,0CAA0C;IAC1C,KAAK,IAAI,IAAI;IAOb,sEAAsE;IACtE,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,8FAA8F;IAC9F,gBAAgB,CAAC,SAAS,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3D,mCAAmC;YACrB,WAAW;IAyCzB,uDAAuD;YACzC,WAAW;CAmN1B;AAED,eAAO,MAAM,oBAAoB,sBAA6B,CAAA"}
|