@glassly/engine 0.1.0-dev.99 → 0.2.9-beta.448
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 +28 -0
- package/build/engine.d.ts +32 -10
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +24 -16
- package/build/engine.js.map +1 -1
- package/build/facades/dev.d.ts +9 -0
- package/build/facades/dev.d.ts.map +1 -1
- package/build/facades/dev.js +9 -0
- package/build/facades/dev.js.map +1 -1
- package/build/facades/display.d.ts +10 -3
- package/build/facades/display.d.ts.map +1 -1
- package/build/facades/display.js +22 -8
- package/build/facades/display.js.map +1 -1
- package/build/facades/displayMirror.d.ts +11 -0
- package/build/facades/displayMirror.d.ts.map +1 -1
- package/build/facades/displayMirror.js +22 -0
- package/build/facades/displayMirror.js.map +1 -1
- package/build/facades/glasses.d.ts +31 -1
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +51 -0
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/memory.d.ts +0 -6
- package/build/facades/memory.d.ts.map +1 -1
- package/build/facades/memory.js +1 -9
- package/build/facades/memory.js.map +1 -1
- package/build/facades/miniapps.d.ts +3 -1
- package/build/facades/miniapps.d.ts.map +1 -1
- package/build/facades/miniapps.js +3 -1
- package/build/facades/miniapps.js.map +1 -1
- package/build/facades/pairing.d.ts.map +1 -1
- package/build/facades/pairing.js +5 -4
- package/build/facades/pairing.js.map +1 -1
- package/build/facades/permissions.d.ts +2 -0
- package/build/facades/permissions.d.ts.map +1 -1
- package/build/facades/permissions.js +48 -0
- package/build/facades/permissions.js.map +1 -1
- package/build/facades/phoneNotifications.d.ts +20 -9
- package/build/facades/phoneNotifications.d.ts.map +1 -1
- package/build/facades/phoneNotifications.js +33 -26
- package/build/facades/phoneNotifications.js.map +1 -1
- package/build/facades/settings.d.ts.map +1 -1
- package/build/facades/settings.js +1 -2
- package/build/facades/settings.js.map +1 -1
- package/build/generated/releaseMetadata.js +4 -4
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +6 -4
- package/build/index.d.ts.map +1 -1
- package/build/index.js +5 -4
- package/build/index.js.map +1 -1
- package/build/react/MentraLiveOtaFlow.js +2 -2
- package/build/react/MentraLiveOtaFlow.js.map +1 -1
- package/build/react/useMentraLiveOta.d.ts.map +1 -1
- package/build/react/useMentraLiveOta.js +8 -7
- package/build/react/useMentraLiveOta.js.map +1 -1
- package/build/runtime/config.d.ts +1 -1
- package/build/runtime/config.d.ts.map +1 -1
- package/build/runtime/config.js.map +1 -1
- package/build/services/AppRegistry.d.ts +4 -1
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +21 -1
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/BlobStore.d.ts +2 -2
- package/build/services/BlobStore.js +3 -3
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudClientService.d.ts +7 -3
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +34 -9
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DevServerBridge.d.ts +1 -18
- package/build/services/DevServerBridge.d.ts.map +1 -1
- package/build/services/DevServerBridge.js +9 -8
- package/build/services/DevServerBridge.js.map +1 -1
- package/build/services/DeviceEventRouter.d.ts.map +1 -1
- package/build/services/DeviceEventRouter.js +58 -71
- package/build/services/DeviceEventRouter.js.map +1 -1
- package/build/services/DisplayDiagnostics.d.ts +5 -0
- package/build/services/DisplayDiagnostics.d.ts.map +1 -0
- package/build/services/DisplayDiagnostics.js +105 -0
- package/build/services/DisplayDiagnostics.js.map +1 -0
- package/build/services/DisplayProcessor.d.ts +6 -7
- package/build/services/DisplayProcessor.d.ts.map +1 -1
- package/build/services/DisplayProcessor.js +17 -45
- package/build/services/DisplayProcessor.js.map +1 -1
- package/build/services/GestureDotsService.d.ts +10 -4
- package/build/services/GestureDotsService.d.ts.map +1 -1
- package/build/services/GestureDotsService.js +70 -16
- package/build/services/GestureDotsService.js.map +1 -1
- package/build/services/GlassesKeyboardInput.d.ts +77 -0
- package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
- package/build/services/GlassesKeyboardInput.js +261 -0
- package/build/services/GlassesKeyboardInput.js.map +1 -0
- package/build/services/GlassesSensorService.d.ts +47 -0
- package/build/services/GlassesSensorService.d.ts.map +1 -0
- package/build/services/GlassesSensorService.js +242 -0
- package/build/services/GlassesSensorService.js.map +1 -0
- package/build/services/GlassesTouchInput.d.ts +14 -0
- package/build/services/GlassesTouchInput.d.ts.map +1 -0
- package/build/services/GlassesTouchInput.js +107 -0
- package/build/services/GlassesTouchInput.js.map +1 -0
- package/build/services/HeadingService.d.ts +0 -6
- package/build/services/HeadingService.d.ts.map +1 -1
- package/build/services/HeadingService.js +0 -27
- package/build/services/HeadingService.js.map +1 -1
- package/build/services/HotspotShutdown.d.ts.map +1 -1
- package/build/services/HotspotShutdown.js +2 -1
- package/build/services/HotspotShutdown.js.map +1 -1
- package/build/services/JSCrashloopReportService.js +2 -2
- package/build/services/JSCrashloopReportService.js.map +1 -1
- package/build/services/JSRouter.d.ts +6 -4
- package/build/services/JSRouter.d.ts.map +1 -1
- package/build/services/JSRouter.js +15 -13
- package/build/services/JSRouter.js.map +1 -1
- package/build/services/LocalDisplayManager.d.ts +35 -7
- package/build/services/LocalDisplayManager.d.ts.map +1 -1
- package/build/services/LocalDisplayManager.js +105 -27
- package/build/services/LocalDisplayManager.js.map +1 -1
- package/build/services/LocalMiniappDataMigration.d.ts +1 -1
- package/build/services/LocalMiniappDataMigration.js +1 -1
- package/build/services/LocalMiniappDataMigration.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +64 -11
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +441 -35
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js +27 -8
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/MemoryStore.d.ts +8 -33
- package/build/services/MemoryStore.d.ts.map +1 -1
- package/build/services/MemoryStore.js +30 -56
- package/build/services/MemoryStore.js.map +1 -1
- package/build/services/MiniappEngine.d.ts +3 -3
- package/build/services/MiniappEngine.js +7 -7
- package/build/services/MiniappEngine.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts +8 -0
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +19 -1
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/MirrorService.d.ts +24 -0
- package/build/services/MirrorService.d.ts.map +1 -0
- package/build/services/MirrorService.js +132 -0
- package/build/services/MirrorService.js.map +1 -0
- package/build/services/NativeNavigationService.d.ts +2 -3
- package/build/services/NativeNavigationService.d.ts.map +1 -1
- package/build/services/NativeNavigationService.js +24 -21
- package/build/services/NativeNavigationService.js.map +1 -1
- package/build/services/NavigationHandlers.d.ts.map +1 -1
- package/build/services/NavigationHandlers.js +10 -5
- package/build/services/NavigationHandlers.js.map +1 -1
- package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
- package/build/services/OtaInstallCoordinator.js +24 -23
- package/build/services/OtaInstallCoordinator.js.map +1 -1
- package/build/services/PairedGlassesLatch.d.ts +7 -0
- package/build/services/PairedGlassesLatch.d.ts.map +1 -0
- package/build/services/PairedGlassesLatch.js +38 -0
- package/build/services/PairedGlassesLatch.js.map +1 -0
- package/build/services/PhoneActivity.d.ts +23 -0
- package/build/services/PhoneActivity.d.ts.map +1 -0
- package/build/services/PhoneActivity.js +111 -0
- package/build/services/PhoneActivity.js.map +1 -0
- package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
- package/build/services/PhoneCameraFovCoordinator.js +4 -3
- package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
- package/build/services/PhoneNotificationsSync.d.ts +40 -6
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +160 -84
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
- package/build/services/PhonePhotoCoordinator.js +6 -5
- package/build/services/PhonePhotoCoordinator.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js +8 -7
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/STTModelManager.d.ts +3 -0
- package/build/services/STTModelManager.d.ts.map +1 -1
- package/build/services/STTModelManager.js +15 -1
- package/build/services/STTModelManager.js.map +1 -1
- package/build/services/SceneRenderer.d.ts +43 -2
- package/build/services/SceneRenderer.d.ts.map +1 -1
- package/build/services/SceneRenderer.js +123 -8
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/StreamLifecycleController.d.ts.map +1 -1
- package/build/services/StreamLifecycleController.js +6 -14
- package/build/services/StreamLifecycleController.js.map +1 -1
- package/build/services/TTSModelManager.js +1 -1
- package/build/services/TTSModelManager.js.map +1 -1
- package/build/services/UIRouter.d.ts +2 -2
- package/build/services/UIRouter.js +5 -5
- package/build/services/UIRouter.js.map +1 -1
- package/build/services/asg/galleryPathMigration.js +1 -1
- package/build/services/asg/galleryPathMigration.js.map +1 -1
- package/build/services/asg/gallerySyncService.js +2 -2
- package/build/services/asg/gallerySyncService.js.map +1 -1
- package/build/services/asg/localStorageService.d.ts.map +1 -1
- package/build/services/asg/localStorageService.js +3 -3
- package/build/services/asg/localStorageService.js.map +1 -1
- package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
- package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
- package/build/services/debug/DashboardOpenTrace.js +128 -0
- package/build/services/debug/DashboardOpenTrace.js.map +1 -0
- package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
- package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
- package/build/services/debug/dashboardOpenTimeline.js +195 -0
- package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
- package/build/services/effectiveCapabilities.d.ts.map +1 -1
- package/build/services/effectiveCapabilities.js +25 -13
- package/build/services/effectiveCapabilities.js.map +1 -1
- package/build/services/gestureClaims.d.ts +34 -15
- package/build/services/gestureClaims.d.ts.map +1 -1
- package/build/services/gestureClaims.js +42 -21
- package/build/services/gestureClaims.js.map +1 -1
- package/build/services/manifestFields.d.ts +9 -0
- package/build/services/manifestFields.d.ts.map +1 -0
- package/build/services/manifestFields.js +26 -0
- package/build/services/manifestFields.js.map +1 -0
- package/build/services/memoryStoreInstance.d.ts +0 -10
- package/build/services/memoryStoreInstance.d.ts.map +1 -1
- package/build/services/memoryStoreInstance.js +2 -31
- package/build/services/memoryStoreInstance.js.map +1 -1
- package/build/services/mirrorSnapshot.d.ts +16 -0
- package/build/services/mirrorSnapshot.d.ts.map +1 -0
- package/build/services/mirrorSnapshot.js +102 -0
- package/build/services/mirrorSnapshot.js.map +1 -0
- package/build/services/nativeNavigationGate.d.ts +8 -0
- package/build/services/nativeNavigationGate.d.ts.map +1 -0
- package/build/services/nativeNavigationGate.js +12 -0
- package/build/services/nativeNavigationGate.js.map +1 -0
- package/build/services/notificationAppCatalog.d.ts +7 -0
- package/build/services/notificationAppCatalog.d.ts.map +1 -0
- package/build/services/notificationAppCatalog.js +16 -0
- package/build/services/notificationAppCatalog.js.map +1 -0
- package/build/services/notifications/notificationPolicy.d.ts +55 -0
- package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
- package/build/services/notifications/notificationPolicy.js +41 -0
- package/build/services/notifications/notificationPolicy.js.map +1 -0
- package/build/services/pages/OverlayPages.d.ts +26 -0
- package/build/services/pages/OverlayPages.d.ts.map +1 -0
- package/build/services/pages/OverlayPages.js +80 -0
- package/build/services/pages/OverlayPages.js.map +1 -0
- package/build/services/pages/PageHost.d.ts +32 -0
- package/build/services/pages/PageHost.d.ts.map +1 -0
- package/build/services/pages/PageHost.js +99 -0
- package/build/services/pages/PageHost.js.map +1 -0
- package/build/services/pages/overlayApps.d.ts +25 -0
- package/build/services/pages/overlayApps.d.ts.map +1 -0
- package/build/services/pages/overlayApps.js +66 -0
- package/build/services/pages/overlayApps.js.map +1 -0
- package/build/services/pages/pageEligibility.d.ts +9 -0
- package/build/services/pages/pageEligibility.d.ts.map +1 -0
- package/build/services/pages/pageEligibility.js +27 -0
- package/build/services/pages/pageEligibility.js.map +1 -0
- package/build/services/settingsBridge.d.ts +58 -0
- package/build/services/settingsBridge.d.ts.map +1 -0
- package/build/services/settingsBridge.js +90 -0
- package/build/services/settingsBridge.js.map +1 -0
- package/build/services/speakerProfileStoreInstance.js +1 -1
- package/build/services/speakerProfileStoreInstance.js.map +1 -1
- package/build/services/uiShim.d.ts +1 -1
- package/build/services/uiShim.js +4 -4
- package/build/services/uiShim.js.map +1 -1
- package/build/stores/appVisibility.d.ts +28 -0
- package/build/stores/appVisibility.d.ts.map +1 -1
- package/build/stores/appVisibility.js +34 -0
- package/build/stores/appVisibility.js.map +1 -1
- package/build/stores/apps.d.ts +13 -0
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +66 -12
- package/build/stores/apps.js.map +1 -1
- package/build/stores/bluetoothSettingKeys.js +1 -1
- package/build/stores/bluetoothSettingKeys.js.map +1 -1
- package/build/stores/display.d.ts +3 -3
- package/build/stores/display.d.ts.map +1 -1
- package/build/stores/display.js +16 -4
- package/build/stores/display.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +14 -1
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts +1 -0
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +170 -44
- package/build/stores/settings.js.map +1 -1
- package/build/types/applet.d.ts +14 -1
- package/build/types/applet.d.ts.map +1 -1
- package/build/types/applet.js.map +1 -1
- package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
- package/build/types/capabilities/even-realities-g2.js +5 -0
- package/build/types/capabilities/even-realities-g2.js.map +1 -1
- package/build/types/capabilities/simulated-glasses.d.ts +1 -1
- package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
- package/build/types/capabilities/simulated-glasses.js +7 -4
- package/build/types/capabilities/simulated-glasses.js.map +1 -1
- package/build/types/hardware.d.ts +20 -1
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +2 -0
- package/build/types/hardware.js.map +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/index.js +1 -0
- package/build/types/index.js.map +1 -1
- package/build/utils/debouncedPatch.d.ts +3 -1
- package/build/utils/debouncedPatch.d.ts.map +1 -1
- package/build/utils/debouncedPatch.js +6 -3
- package/build/utils/debouncedPatch.js.map +1 -1
- package/build/utils/devMiniappLaunch.d.ts.map +1 -1
- package/build/utils/devMiniappLaunch.js +4 -3
- package/build/utils/devMiniappLaunch.js.map +1 -1
- package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
- package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
- package/build/utils/display/measurer/TextMeasurer.js +2 -272
- package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
- package/build/utils/display/measurer/script-detection.d.ts +1 -52
- package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
- package/build/utils/display/measurer/script-detection.js +2 -183
- package/build/utils/display/measurer/script-detection.js.map +1 -1
- package/build/utils/display/pixelArt.d.ts +3 -0
- package/build/utils/display/pixelArt.d.ts.map +1 -0
- package/build/utils/display/pixelArt.js +3 -0
- package/build/utils/display/pixelArt.js.map +1 -0
- package/build/utils/display/profiles/g1.d.ts +1 -32
- package/build/utils/display/profiles/g1.d.ts.map +1 -1
- package/build/utils/display/profiles/g1.js +2 -212
- package/build/utils/display/profiles/g1.js.map +1 -1
- package/build/utils/display/profiles/g2.d.ts +1 -12
- package/build/utils/display/profiles/g2.d.ts.map +1 -1
- package/build/utils/display/profiles/g2.js +2 -33
- package/build/utils/display/profiles/g2.js.map +1 -1
- package/build/utils/display/profiles/nex.d.ts +1 -9
- package/build/utils/display/profiles/nex.d.ts.map +1 -1
- package/build/utils/display/profiles/nex.js +2 -149
- package/build/utils/display/profiles/nex.js.map +1 -1
- package/build/utils/display/profiles/types.d.ts +1 -102
- package/build/utils/display/profiles/types.d.ts.map +1 -1
- package/build/utils/display/profiles/types.js.map +1 -1
- package/build/utils/display/profiles/z100.d.ts +1 -32
- package/build/utils/display/profiles/z100.d.ts.map +1 -1
- package/build/utils/display/profiles/z100.js +2 -181
- package/build/utils/display/profiles/z100.js.map +1 -1
- package/build/utils/display/scene/degrade.d.ts.map +1 -1
- package/build/utils/display/scene/degrade.js +4 -1
- package/build/utils/display/scene/degrade.js.map +1 -1
- package/build/utils/display/scene/differ.d.ts +13 -1
- package/build/utils/display/scene/differ.d.ts.map +1 -1
- package/build/utils/display/scene/differ.js +22 -0
- package/build/utils/display/scene/differ.js.map +1 -1
- package/build/utils/display/scene/index.d.ts +1 -1
- package/build/utils/display/scene/index.d.ts.map +1 -1
- package/build/utils/display/scene/index.js.map +1 -1
- package/build/utils/display/scene/process.d.ts.map +1 -1
- package/build/utils/display/scene/process.js +183 -11
- package/build/utils/display/scene/process.js.map +1 -1
- package/build/utils/display/scene/store.d.ts +1 -1
- package/build/utils/display/scene/store.d.ts.map +1 -1
- package/build/utils/display/scene/store.js +0 -0
- package/build/utils/display/scene/store.js.map +1 -1
- package/build/utils/display/scene/svgPath.d.ts +9 -0
- package/build/utils/display/scene/svgPath.d.ts.map +1 -0
- package/build/utils/display/scene/svgPath.js +167 -0
- package/build/utils/display/scene/svgPath.js.map +1 -0
- package/build/utils/display/scene/types.d.ts +2 -142
- package/build/utils/display/scene/types.d.ts.map +1 -1
- package/build/utils/display/scene/types.js +0 -0
- package/build/utils/display/scene/types.js.map +1 -1
- package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
- package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
- package/build/utils/display/wrapper/TextWrapper.js +2 -470
- package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
- package/build/utils/display/wrapper/types.d.ts +2 -74
- package/build/utils/display/wrapper/types.d.ts.map +1 -1
- package/build/utils/display/wrapper/types.js +2 -10
- package/build/utils/display/wrapper/types.js.map +1 -1
- package/build/utils/hardware/hardware.js +1 -1
- package/build/utils/hardware/hardware.js.map +1 -1
- package/build/utils/timers/timers.d.ts.map +1 -1
- package/build/utils/timers/timers.js +26 -4
- package/build/utils/timers/timers.js.map +1 -1
- package/package.json +8 -8
- package/src/engine.ts +24 -15
- package/src/facades/dev.ts +10 -0
- package/src/facades/display.ts +21 -8
- package/src/facades/displayMirror.ts +29 -0
- package/src/facades/glasses.ts +61 -1
- package/src/facades/memory.ts +1 -12
- package/src/facades/miniapps.ts +4 -1
- package/src/facades/pairing.ts +8 -6
- package/src/facades/permissions.ts +46 -0
- package/src/facades/phoneNotifications.ts +45 -26
- package/src/facades/settings.ts +1 -2
- package/src/generated/releaseMetadata.ts +4 -4
- package/src/index.ts +6 -9
- package/src/react/MentraLiveOtaFlow.tsx +2 -2
- package/src/react/useMentraLiveOta.ts +14 -8
- package/src/runtime/config.ts +1 -1
- package/src/services/AppRegistry.ts +43 -7
- package/src/services/BlobStore.ts +3 -3
- package/src/services/CloudClientService.ts +37 -10
- package/src/services/DevServerBridge.ts +12 -10
- package/src/services/DeviceEventRouter.ts +73 -74
- package/src/services/DisplayDiagnostics.ts +107 -0
- package/src/services/DisplayProcessor.ts +20 -55
- package/src/services/GestureDotsService.ts +77 -16
- package/src/services/GlassesKeyboardInput.ts +306 -0
- package/src/services/GlassesSensorService.ts +233 -0
- package/src/services/GlassesTouchInput.ts +128 -0
- package/src/services/HeadingService.ts +0 -24
- package/src/services/HotspotShutdown.ts +3 -1
- package/src/services/JSCrashloopReportService.ts +2 -2
- package/src/services/JSRouter.ts +29 -14
- package/src/services/LocalDisplayManager.ts +112 -26
- package/src/services/LocalMiniappDataMigration.ts +1 -1
- package/src/services/LocalMiniappRuntime.ts +500 -43
- package/src/services/LocalSttFallbackCoordinator.ts +28 -7
- package/src/services/MemoryStore.ts +32 -80
- package/src/services/MiniappEngine.ts +7 -7
- package/src/services/MiniappLauncher.ts +25 -1
- package/src/services/MirrorService.ts +139 -0
- package/src/services/NativeNavigationService.ts +29 -25
- package/src/services/NavigationHandlers.ts +10 -5
- package/src/services/OtaInstallCoordinator.ts +36 -34
- package/src/services/PairedGlassesLatch.ts +39 -0
- package/src/services/PhoneActivity.ts +116 -0
- package/src/services/PhoneCameraFovCoordinator.ts +6 -4
- package/src/services/PhoneNotificationsSync.ts +185 -103
- package/src/services/PhonePhotoCoordinator.ts +9 -10
- package/src/services/PhoneStreamCoordinator.ts +13 -11
- package/src/services/STTModelManager.ts +15 -1
- package/src/services/SceneRenderer.ts +148 -10
- package/src/services/StreamLifecycleController.ts +9 -7
- package/src/services/TTSModelManager.ts +1 -1
- package/src/services/UIRouter.ts +5 -5
- package/src/services/asg/galleryPathMigration.ts +1 -1
- package/src/services/asg/gallerySyncService.ts +2 -2
- package/src/services/asg/localStorageService.ts +3 -3
- package/src/services/debug/DashboardOpenTrace.ts +153 -0
- package/src/services/debug/dashboardOpenTimeline.ts +237 -0
- package/src/services/effectiveCapabilities.ts +32 -13
- package/src/services/gestureClaims.ts +72 -23
- package/src/services/manifestFields.ts +23 -0
- package/src/services/memoryStoreInstance.ts +2 -34
- package/src/services/mirrorSnapshot.ts +116 -0
- package/src/services/nativeNavigationGate.ts +14 -0
- package/src/services/notificationAppCatalog.ts +21 -0
- package/src/services/notifications/notificationPolicy.ts +87 -0
- package/src/services/pages/OverlayPages.ts +86 -0
- package/src/services/pages/PageHost.ts +116 -0
- package/src/services/pages/overlayApps.ts +72 -0
- package/src/services/pages/pageEligibility.ts +30 -0
- package/src/services/settingsBridge.ts +111 -0
- package/src/services/speakerProfileStoreInstance.ts +1 -1
- package/src/services/uiShim.ts +4 -4
- package/src/stores/appVisibility.ts +45 -0
- package/src/stores/apps.ts +110 -32
- package/src/stores/bluetoothSettingKeys.ts +1 -1
- package/src/stores/display.ts +18 -7
- package/src/stores/glasses.ts +15 -1
- package/src/stores/settings.ts +175 -51
- package/src/types/applet.ts +14 -1
- package/src/types/capabilities/even-realities-g2.ts +6 -0
- package/src/types/capabilities/simulated-glasses.ts +8 -4
- package/src/types/hardware.ts +34 -1
- package/src/types/index.ts +1 -0
- package/src/utils/debouncedPatch.ts +8 -4
- package/src/utils/devMiniappLaunch.ts +5 -3
- package/src/utils/display/measurer/TextMeasurer.ts +3 -346
- package/src/utils/display/measurer/script-detection.ts +10 -218
- package/src/utils/display/pixelArt.ts +3 -0
- package/src/utils/display/profiles/g1.ts +2 -236
- package/src/utils/display/profiles/g2.ts +2 -39
- package/src/utils/display/profiles/nex.ts +2 -166
- package/src/utils/display/profiles/types.ts +9 -132
- package/src/utils/display/profiles/z100.ts +2 -198
- package/src/utils/display/scene/degrade.ts +4 -1
- package/src/utils/display/scene/differ.ts +25 -1
- package/src/utils/display/scene/index.ts +5 -0
- package/src/utils/display/scene/process.ts +196 -13
- package/src/utils/display/scene/store.ts +0 -0
- package/src/utils/display/scene/svgPath.ts +163 -0
- package/src/utils/display/scene/types.ts +0 -0
- package/src/utils/display/wrapper/TextWrapper.ts +2 -546
- package/src/utils/display/wrapper/types.ts +3 -102
- package/src/utils/hardware/hardware.ts +1 -1
- package/src/utils/timers/timers.ts +32 -4
- package/build/services/CustomDashboardModel.d.ts +0 -48
- package/build/services/CustomDashboardModel.d.ts.map +0 -1
- package/build/services/CustomDashboardModel.js +0 -73
- package/build/services/CustomDashboardModel.js.map +0 -1
- package/build/services/CustomDashboardService.d.ts +0 -63
- package/build/services/CustomDashboardService.d.ts.map +0 -1
- package/build/services/CustomDashboardService.js +0 -576
- package/build/services/CustomDashboardService.js.map +0 -1
- package/build/services/DashboardCoordinator.d.ts +0 -26
- package/build/services/DashboardCoordinator.d.ts.map +0 -1
- package/build/services/DashboardCoordinator.js +0 -125
- package/build/services/DashboardCoordinator.js.map +0 -1
- package/build/services/iosNotificationAppCatalog.d.ts +0 -13
- package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
- package/build/services/iosNotificationAppCatalog.js +0 -28
- package/build/services/iosNotificationAppCatalog.js.map +0 -1
- package/src/services/CustomDashboardModel.ts +0 -83
- package/src/services/CustomDashboardService.ts +0 -598
- package/src/services/DashboardCoordinator.ts +0 -121
- package/src/services/iosNotificationAppCatalog.ts +0 -39
|
@@ -114,6 +114,52 @@ function androidPerms(feature: string): AndroidPermission[] {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
export const permissions = {
|
|
117
|
+
/** Missing required miniapp grants, checked without prompting. CAMERA is the glasses camera. */
|
|
118
|
+
async missingRequired(requirements: readonly AppletPermission[]): Promise<string[]> {
|
|
119
|
+
const features = new Set<string>()
|
|
120
|
+
for (const permission of requirements) {
|
|
121
|
+
if (permission.required === false) continue
|
|
122
|
+
switch (permission.type) {
|
|
123
|
+
case "ALL":
|
|
124
|
+
features.add(PermissionFeatures.MICROPHONE)
|
|
125
|
+
features.add(PermissionFeatures.CALENDAR)
|
|
126
|
+
features.add(PermissionFeatures.LOCATION)
|
|
127
|
+
features.add(PermissionFeatures.BACKGROUND_LOCATION)
|
|
128
|
+
features.add(PermissionFeatures.POST_NOTIFICATIONS)
|
|
129
|
+
features.add("read_notifications")
|
|
130
|
+
break
|
|
131
|
+
case "MICROPHONE":
|
|
132
|
+
case "CALENDAR":
|
|
133
|
+
case "LOCATION":
|
|
134
|
+
case "BACKGROUND_LOCATION":
|
|
135
|
+
case "POST_NOTIFICATIONS":
|
|
136
|
+
features.add(PermissionFeatures[permission.type])
|
|
137
|
+
break
|
|
138
|
+
case "READ_NOTIFICATIONS":
|
|
139
|
+
features.add("read_notifications")
|
|
140
|
+
break
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const missing: string[] = []
|
|
145
|
+
for (const feature of features) {
|
|
146
|
+
let granted: boolean
|
|
147
|
+
if (feature === "read_notifications") {
|
|
148
|
+
// iOS glasses read notifications directly; Android uses the phone's listener.
|
|
149
|
+
granted =
|
|
150
|
+
Platform.OS !== "android" ||
|
|
151
|
+
(await (await import("@glassly/crust")).default.hasNotificationListenerPermission())
|
|
152
|
+
} else if (feature === PermissionFeatures.CALENDAR && Platform.OS === "ios") {
|
|
153
|
+
// EventKit must allow reads; a scoped/write-only OS grant is insufficient.
|
|
154
|
+
granted = (await (await import("expo-calendar")).getCalendarPermissions()).status === "granted"
|
|
155
|
+
} else {
|
|
156
|
+
granted = await permissions.check(feature)
|
|
157
|
+
}
|
|
158
|
+
if (!granted) missing.push(feature)
|
|
159
|
+
}
|
|
160
|
+
return missing
|
|
161
|
+
},
|
|
162
|
+
|
|
117
163
|
/** Is the given feature's OS permission currently granted? */
|
|
118
164
|
async check(feature: string): Promise<boolean> {
|
|
119
165
|
if (Platform.OS === "android") {
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* phoneNotifications facade — `engine.phoneNotifications`:
|
|
3
|
-
*
|
|
2
|
+
* phoneNotifications facade — `engine.phoneNotifications`: phone notifications
|
|
3
|
+
* on the glasses, with a per-app blocklist and one presentation owner.
|
|
4
4
|
*
|
|
5
|
-
* Android
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* authorization (`glasses.ancsAuthorized`), not by this facade.
|
|
5
|
+
* Capture is the phone's (Android listener) or the glasses' (iOS, reading the
|
|
6
|
+
* phone's stream) business and is never gated here. Presentation is decided
|
|
7
|
+
* by `presentationOwner`: the engine's viewer on Glassly CFW glasses, the
|
|
8
|
+
* firmware on glasses with their own notification centre, else the host's
|
|
9
|
+
* card while its surface (Notify) runs. The four display settings drive
|
|
10
|
+
* firmware and viewer alike; PhoneNotificationsSync pushes them.
|
|
12
11
|
*/
|
|
13
12
|
import {Platform} from "react-native"
|
|
14
13
|
import CrustModule from "@glassly/crust"
|
|
14
|
+
import type {PhoneNotificationEvent} from "@glassly/crust"
|
|
15
|
+
import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
|
|
16
|
+
import type {GlassesNotificationStatus, NotificationUploadResult} from "@glassly/bluetooth-sdk"
|
|
15
17
|
import {useSettingsStore, SETTINGS} from "../stores/settings"
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
+
import {
|
|
19
|
+
captureAuthorization,
|
|
20
|
+
currentPresentationOwner,
|
|
21
|
+
installedNotificationApps,
|
|
22
|
+
nativeNotificationPopupSeconds,
|
|
23
|
+
nativeNotificationsSupported,
|
|
24
|
+
uploadPhoneNotification,
|
|
25
|
+
} from "../services/PhoneNotificationsSync"
|
|
18
26
|
|
|
19
27
|
export const phoneNotifications = {
|
|
20
28
|
/**
|
|
@@ -22,17 +30,7 @@ export const phoneNotifications = {
|
|
|
22
30
|
* Android: installed apps. iOS: seeded catalog ∪ glasses-reported apps
|
|
23
31
|
* (icons unavailable — iOS offers no cross-app icon lookup).
|
|
24
32
|
*/
|
|
25
|
-
installedApps:
|
|
26
|
-
if (Platform.OS === "android") return CrustModule.getInstalledApps()
|
|
27
|
-
if (Platform.OS !== "ios") return Promise.resolve([])
|
|
28
|
-
return Promise.resolve(
|
|
29
|
-
getKnownNotificationApps().map((app) => ({
|
|
30
|
-
packageName: app.appId,
|
|
31
|
-
appName: app.displayName,
|
|
32
|
-
icon: null,
|
|
33
|
-
})),
|
|
34
|
-
)
|
|
35
|
-
},
|
|
33
|
+
installedApps: installedNotificationApps,
|
|
36
34
|
|
|
37
35
|
/** The per-app blocklist (package/bundle ids whose notifications are NOT forwarded). */
|
|
38
36
|
blocklist: (): string[] => {
|
|
@@ -54,10 +52,31 @@ export const phoneNotifications = {
|
|
|
54
52
|
return CrustModule.openNotificationListenerSettings()
|
|
55
53
|
},
|
|
56
54
|
|
|
55
|
+
/** Whether the glasses may read the phone's notifications; `not_needed` where the phone captures. */
|
|
56
|
+
captureAuthorization,
|
|
57
|
+
|
|
58
|
+
/** The connected model presents notifications in firmware. */
|
|
59
|
+
nativeNotifications: nativeNotificationsSupported,
|
|
60
|
+
/** Popup durations the firmware accepts (seconds, 0 = its default); empty when any value goes. */
|
|
61
|
+
popupSecondsOptions: nativeNotificationPopupSeconds,
|
|
62
|
+
|
|
57
63
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* on Android — Android capture is the notification listener instead.
|
|
64
|
+
* Who presents the next phone notification. Hosts pass whether their own
|
|
65
|
+
* surface runs and draw only when the answer is `host`.
|
|
61
66
|
*/
|
|
62
|
-
|
|
67
|
+
presentationOwner: currentPresentationOwner,
|
|
68
|
+
/** Hand a captured notification to firmware that presents uploaded content (owner `firmware`, Android). */
|
|
69
|
+
uploadToGlasses: (event: PhoneNotificationEvent): Promise<void> => uploadPhoneNotification(event),
|
|
70
|
+
|
|
71
|
+
/** The driver's view of its notification surface. */
|
|
72
|
+
glassesStatus: (): Promise<GlassesNotificationStatus> => BluetoothSdk.getGlassesNotificationStatus(),
|
|
73
|
+
onGlassesStatus: (listener: (status: GlassesNotificationStatus) => void): (() => void) => {
|
|
74
|
+
const subscription = BluetoothSdk.addListener("glasses_notification_status", listener)
|
|
75
|
+
return () => subscription.remove()
|
|
76
|
+
},
|
|
77
|
+
/** Upload outcomes by id; content never travels back. */
|
|
78
|
+
onUploadResult: (listener: (result: NotificationUploadResult) => void): (() => void) => {
|
|
79
|
+
const subscription = BluetoothSdk.addListener("notification_upload_result", listener)
|
|
80
|
+
return () => subscription.remove()
|
|
81
|
+
},
|
|
63
82
|
}
|
package/src/facades/settings.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* settings facade — `engine.settings`: the typed keyed user-settings surface over
|
|
3
|
-
* the engine-owned settings store. This is the
|
|
4
|
-
* `engine.stores.settings` is the Glassly-app escape hatch.
|
|
3
|
+
* the engine-owned settings store. This is the OEM contract.
|
|
5
4
|
*
|
|
6
5
|
* Keys + their schema live in `SETTINGS` (theme, devMode, metric/twelveHourTime,
|
|
7
6
|
* notifications, onboarding flags, …); `descriptor(key)`/`keys()` expose them.
|
|
@@ -11,10 +11,10 @@ export interface EngineReleaseMetadata {
|
|
|
11
11
|
|
|
12
12
|
export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
|
|
13
13
|
"schemaVersion": 1,
|
|
14
|
-
"familyBaseVersion": "0.
|
|
15
|
-
"releaseIdentity": "0.
|
|
16
|
-
"releaseSetId": "glassly-0.
|
|
17
|
-
"sourceCommit": "
|
|
14
|
+
"familyBaseVersion": "0.2.9",
|
|
15
|
+
"releaseIdentity": "0.2.9-beta.448",
|
|
16
|
+
"releaseSetId": "glassly-0.2.9-beta.448",
|
|
17
|
+
"sourceCommit": "257d1118deffd395f97babc54c306965038102a7",
|
|
18
18
|
"otaManifestUrl": null,
|
|
19
19
|
"otaManifestSha256": null
|
|
20
20
|
})
|
package/src/index.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* renders with (decision functions, sort/order helpers, policy constants,
|
|
7
7
|
* capability tables, timers). Judgment rule: read models, commands, pure
|
|
8
8
|
* functions and types belong here; anything that mutates runtime state or
|
|
9
|
-
* exposes a raw store/service remains private to the
|
|
9
|
+
* exposes a raw store/service remains private to the Glassly host.
|
|
10
10
|
* See cloud-v2/docs/issues/020-glasses-status-boundary/integration-review.md §D.
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -22,6 +22,8 @@ export type {
|
|
|
22
22
|
EngineSubmitReportInput,
|
|
23
23
|
} from "./facades/reports"
|
|
24
24
|
export type {IslandNotification, IslandNotificationKind} from "./facades/notifications"
|
|
25
|
+
export type {PresentationOwner} from "./services/notifications/notificationPolicy"
|
|
26
|
+
export {DEFAULT_HIDDEN_PACKAGES} from "./stores/appVisibility"
|
|
25
27
|
export type {WifiSearchResult} from "./facades/glassesWifi"
|
|
26
28
|
export type {IdentitySnapshot} from "./services/PairingIdentity"
|
|
27
29
|
export type {DisplayMirrorEvent} from "./facades/displayMirror"
|
|
@@ -41,14 +43,8 @@ export type {
|
|
|
41
43
|
// (the hook layer, same precedent as the apps hooks below), and the pure
|
|
42
44
|
// device-model key helpers. The raw useSettingsStore stays internal;
|
|
43
45
|
// imperative access goes through engine.settings.
|
|
44
|
-
export {SETTINGS, useSetting} from "./stores/settings"
|
|
45
|
-
export {
|
|
46
|
-
isCustomDashboardEligible,
|
|
47
|
-
normalizeDashboardWidgets,
|
|
48
|
-
DASHBOARD_WIDGET_IDS,
|
|
49
|
-
type DashboardWidgetId,
|
|
50
|
-
type DashboardWidgetSetting,
|
|
51
|
-
} from "./services/CustomDashboardModel"
|
|
46
|
+
export {SETTINGS, useSetting, AI_DATA_CONSENT_VERSION} from "./stores/settings"
|
|
47
|
+
export {isCfwFirmwareVersion, isCustomDashboardEligible} from "./services/pages/pageEligibility"
|
|
52
48
|
|
|
53
49
|
// AI tier registry: the curated per-tier model dropdown options and helpers
|
|
54
50
|
// the Settings > AI Models screen renders. Resolution itself runs inside
|
|
@@ -185,6 +181,7 @@ export {
|
|
|
185
181
|
useInstall,
|
|
186
182
|
useUninstall,
|
|
187
183
|
useActiveApps,
|
|
184
|
+
useRunningPersistentApps,
|
|
188
185
|
useActiveBackgroundApps,
|
|
189
186
|
useBackgroundApps,
|
|
190
187
|
useActiveForegroundApp,
|
|
@@ -159,7 +159,7 @@ export function MentraLiveOtaFlow({
|
|
|
159
159
|
<SafeAreaView style={[styles.safeArea, {backgroundColor: colors.background}, style]}>
|
|
160
160
|
<View style={styles.header}>
|
|
161
161
|
<View />
|
|
162
|
-
<
|
|
162
|
+
<BrandMark color={colors.primary} />
|
|
163
163
|
</View>
|
|
164
164
|
<OtaFlowContent
|
|
165
165
|
allowDevSkip={allowDevSkip}
|
|
@@ -688,7 +688,7 @@ function FlowButton({
|
|
|
688
688
|
)
|
|
689
689
|
}
|
|
690
690
|
|
|
691
|
-
function
|
|
691
|
+
function BrandMark({color}: {color: string}) {
|
|
692
692
|
return (
|
|
693
693
|
<Svg width={33} height={18} viewBox="0 0 50 27" fill="none">
|
|
694
694
|
<Rect y={14.8072} width={11.8457} height={11.8457} fill={color} />
|
|
@@ -23,6 +23,8 @@ import type {OtaCheckCurrentGlassesResult} from "../services/OtaUpdateCheckServi
|
|
|
23
23
|
import type {ReleaseChangelog} from "../facades/ota"
|
|
24
24
|
import {useEngineSnapshot} from "./useEngineSnapshot"
|
|
25
25
|
|
|
26
|
+
import {BgTimer} from "../utils/timers"
|
|
27
|
+
|
|
26
28
|
export type MentraLiveOtaFlowPage = "check" | "progress"
|
|
27
29
|
|
|
28
30
|
export type MentraLiveOtaScreen =
|
|
@@ -306,14 +308,14 @@ export function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraL
|
|
|
306
308
|
|
|
307
309
|
const myGeneration = ++performCheckGenerationRef.current
|
|
308
310
|
let cancelled = false
|
|
309
|
-
let reconnectTimeout:
|
|
311
|
+
let reconnectTimeout: number | null = null
|
|
310
312
|
|
|
311
313
|
const performCheck = async () => {
|
|
312
314
|
if (checkCompletedRef.current) return
|
|
313
315
|
if (isOtaAutoChainActive() && !otaSnapshot.ready) {
|
|
314
316
|
const remainingMs = otaAutoChainReconnectWaitRemaining()
|
|
315
317
|
if (remainingMs === null) return
|
|
316
|
-
reconnectTimeout = setTimeout(() => {
|
|
318
|
+
reconnectTimeout = BgTimer.setTimeout(() => {
|
|
317
319
|
if (cancelled || myGeneration !== performCheckGenerationRef.current || ota.snapshot().ready) return
|
|
318
320
|
stopOtaAutoChain()
|
|
319
321
|
checkCompletedRef.current = true
|
|
@@ -347,13 +349,15 @@ export function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraL
|
|
|
347
349
|
let result = await ota.checkForUpdates(checkOptions)
|
|
348
350
|
if (cancelled || myGeneration !== performCheckGenerationRef.current) return
|
|
349
351
|
if (!result.hasCheckCompleted && result.checkFailureReason === "network" && isOtaAutoChainActive()) {
|
|
350
|
-
await new Promise((resolve) => setTimeout(resolve, AUTO_CHAIN_NETWORK_RETRY_DELAY_MS))
|
|
352
|
+
await new Promise<void>((resolve) => BgTimer.setTimeout(resolve, AUTO_CHAIN_NETWORK_RETRY_DELAY_MS))
|
|
351
353
|
if (cancelled || myGeneration !== performCheckGenerationRef.current) return
|
|
352
354
|
result = await ota.checkForUpdates(checkOptions)
|
|
353
355
|
}
|
|
354
356
|
if (cancelled || myGeneration !== performCheckGenerationRef.current) return
|
|
355
357
|
selectedCheckResultRef.current = result
|
|
356
|
-
await new Promise((resolve) =>
|
|
358
|
+
await new Promise<void>((resolve) =>
|
|
359
|
+
BgTimer.setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))),
|
|
360
|
+
)
|
|
357
361
|
if (cancelled || myGeneration !== performCheckGenerationRef.current) return
|
|
358
362
|
|
|
359
363
|
if (result.skippedReason === "disconnected") {
|
|
@@ -416,7 +420,9 @@ export function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraL
|
|
|
416
420
|
setCheckState("no_update")
|
|
417
421
|
} catch (error) {
|
|
418
422
|
console.error("OTA check failed:", error)
|
|
419
|
-
await new Promise((resolve) =>
|
|
423
|
+
await new Promise<void>((resolve) =>
|
|
424
|
+
BgTimer.setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))),
|
|
425
|
+
)
|
|
420
426
|
if (cancelled || myGeneration !== performCheckGenerationRef.current) return
|
|
421
427
|
stopOtaAutoChain()
|
|
422
428
|
checkCompletedRef.current = true
|
|
@@ -428,7 +434,7 @@ export function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraL
|
|
|
428
434
|
void performCheck()
|
|
429
435
|
return () => {
|
|
430
436
|
cancelled = true
|
|
431
|
-
if (reconnectTimeout) clearTimeout(reconnectTimeout)
|
|
437
|
+
if (reconnectTimeout) BgTimer.clearTimeout(reconnectTimeout)
|
|
432
438
|
}
|
|
433
439
|
}, [
|
|
434
440
|
checkGeneration,
|
|
@@ -500,13 +506,13 @@ export function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraL
|
|
|
500
506
|
) {
|
|
501
507
|
return
|
|
502
508
|
}
|
|
503
|
-
const timeout = setTimeout(async () => {
|
|
509
|
+
const timeout = BgTimer.setTimeout(async () => {
|
|
504
510
|
if (!isOtaAutoChainActive()) return
|
|
505
511
|
autoChainAdvancedRef.current = true
|
|
506
512
|
await ota.installSession.finish()
|
|
507
513
|
returnToCheck()
|
|
508
514
|
}, AUTO_CHAIN_COMPLETE_DELAY_MS)
|
|
509
|
-
return () => clearTimeout(timeout)
|
|
515
|
+
return () => BgTimer.clearTimeout(timeout)
|
|
510
516
|
}, [installSnapshot.connected, installSnapshot.displayState, page, returnToCheck])
|
|
511
517
|
|
|
512
518
|
const check = useCallback(() => {
|
package/src/runtime/config.ts
CHANGED
|
@@ -29,6 +29,7 @@ import {storage} from "../utils/storage/storage"
|
|
|
29
29
|
import {printDirectory} from "../utils/storage/zip"
|
|
30
30
|
import {checkManifestVersions} from "./manifestVersionGate"
|
|
31
31
|
import {normalizeManifestActions} from "./manifestActions"
|
|
32
|
+
import {normalizeManifestTags, normalizeManifestText} from "./manifestFields"
|
|
32
33
|
import {miniappRunningRegistry} from "./MiniappRunningRegistry"
|
|
33
34
|
|
|
34
35
|
export {normalizeManifestActions} from "./manifestActions"
|
|
@@ -40,6 +41,7 @@ const ALLOWED_PERMISSION_TYPES: ReadonlySet<AppPermissionType> = new Set<AppPerm
|
|
|
40
41
|
"LOCATION",
|
|
41
42
|
"BACKGROUND_LOCATION",
|
|
42
43
|
"READ_NOTIFICATIONS",
|
|
44
|
+
"DISPLAY_MIRROR",
|
|
43
45
|
"POST_NOTIFICATIONS",
|
|
44
46
|
"API_KEYS",
|
|
45
47
|
])
|
|
@@ -141,7 +143,7 @@ interface InstalledLma {
|
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
export interface MiniappReleaseIdentity {
|
|
144
|
-
source: "direct_download" | "bundled_asset" | "preinstalled_registry" | "dev_snapshot"
|
|
146
|
+
source: "direct_download" | "bundled_asset" | "preinstalled_registry" | "dev_snapshot" | "store"
|
|
145
147
|
releaseId?: string
|
|
146
148
|
bundleSha256?: string
|
|
147
149
|
channel?: string
|
|
@@ -750,12 +752,25 @@ class AppRegistry {
|
|
|
750
752
|
permissions?: Array<string | {type: string; required?: boolean; description?: string}>
|
|
751
753
|
hardwareRequirements?: Array<{type: string; level: string; description?: string}>
|
|
752
754
|
type?: string
|
|
753
|
-
|
|
755
|
+
persistent?: unknown
|
|
756
|
+
description?: unknown
|
|
757
|
+
tagline?: unknown
|
|
758
|
+
tags?: unknown
|
|
759
|
+
actions?: Array<{
|
|
760
|
+
id?: unknown
|
|
761
|
+
description?: unknown
|
|
762
|
+
parameters?: unknown
|
|
763
|
+
outputSchema?: unknown
|
|
764
|
+
visibility?: unknown
|
|
765
|
+
}>
|
|
754
766
|
} | null
|
|
755
767
|
|
|
756
768
|
const permissions = normalizeManifestPermissions(manifest?.permissions)
|
|
757
769
|
const hardwareRequirements = buildHardwareRequirements(manifest?.hardwareRequirements, lmaInfo.packageName)
|
|
758
770
|
const appType = normalizeManifestType(manifest?.type)
|
|
771
|
+
const description = normalizeManifestText(manifest?.description)
|
|
772
|
+
const tagline = normalizeManifestText(manifest?.tagline)
|
|
773
|
+
const tags = normalizeManifestTags(manifest?.tags)
|
|
759
774
|
|
|
760
775
|
// Declared actions (for session.miniapps.list + invoke gating).
|
|
761
776
|
const actions = normalizeManifestActions(manifest?.actions)
|
|
@@ -783,8 +798,12 @@ class AppRegistry {
|
|
|
783
798
|
webviewUrl: "",
|
|
784
799
|
logoUrl: versionInfo.logoUrl,
|
|
785
800
|
type: appType,
|
|
801
|
+
persistent: getPersistentOverride(lmaInfo.packageName) ?? manifest?.persistent === true,
|
|
786
802
|
permissions,
|
|
787
803
|
hardwareRequirements,
|
|
804
|
+
...(description ? {description} : {}),
|
|
805
|
+
...(tagline ? {tagline} : {}),
|
|
806
|
+
...(tags.length > 0 ? {tags} : {}),
|
|
788
807
|
// Always project actions (even []) so the invoke gate can enforce
|
|
789
808
|
// declared-action membership unconditionally — an app with no declared
|
|
790
809
|
// actions must reject every invoke, not bypass the check.
|
|
@@ -927,6 +946,16 @@ export function getLocalAppRunningState(packageName: string): boolean {
|
|
|
927
946
|
return false
|
|
928
947
|
}
|
|
929
948
|
|
|
949
|
+
/** The wearer's persistent choice for a miniapp, beside the `_hidden` flag; null when they never chose. */
|
|
950
|
+
export function getPersistentOverride(packageName: string): boolean | null {
|
|
951
|
+
const res = storage.load<boolean>(`${packageName}_persistent`)
|
|
952
|
+
return res.is_ok() ? res.value : null
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
export function savePersistentOverride(packageName: string, status: boolean): void {
|
|
956
|
+
storage.save(`${packageName}_persistent`, status)
|
|
957
|
+
}
|
|
958
|
+
|
|
930
959
|
export function getLocalAppScreenshot(packageName: string): string | undefined {
|
|
931
960
|
const key = `${packageName}_screenshot`
|
|
932
961
|
const res = storage.load<string>(key)
|
|
@@ -974,7 +1003,13 @@ export interface DevAppRecord {
|
|
|
974
1003
|
permissions?: Array<string | {type: string; required?: boolean; description?: string}>
|
|
975
1004
|
hardwareRequirements?: Array<{type: string; level: string; description?: string}>
|
|
976
1005
|
/** Manifest-declared actions — so dev-sideloaded miniapps can be invoked too. */
|
|
977
|
-
actions?: Array<{
|
|
1006
|
+
actions?: Array<{
|
|
1007
|
+
id?: unknown
|
|
1008
|
+
description?: unknown
|
|
1009
|
+
parameters?: unknown
|
|
1010
|
+
outputSchema?: unknown
|
|
1011
|
+
visibility?: unknown
|
|
1012
|
+
}>
|
|
978
1013
|
/** Legacy single-slot migration field. New records use the real packageName directly. */
|
|
979
1014
|
sourcePackageName?: string
|
|
980
1015
|
/**
|
|
@@ -988,7 +1023,6 @@ export interface DevAppRecord {
|
|
|
988
1023
|
const DEV_APPS_INDEX_KEY = "dev_apps_index"
|
|
989
1024
|
const DEV_APP_ICONS_DIR = "dev-miniapp-icons"
|
|
990
1025
|
|
|
991
|
-
|
|
992
1026
|
function isPrivateLanHost(hostname: string): boolean {
|
|
993
1027
|
return (
|
|
994
1028
|
hostname === "localhost" ||
|
|
@@ -1044,7 +1078,10 @@ async function cacheDevAppIcon(packageName: string, iconUrl: string): Promise<st
|
|
|
1044
1078
|
// Keep the decoder-friendly .png fallback; image loaders sniff content.
|
|
1045
1079
|
}
|
|
1046
1080
|
|
|
1047
|
-
|
|
1081
|
+
// Image loaders cache file:// URIs too. Replacing bytes at the same path
|
|
1082
|
+
// leaves the old decoded icon visible after rescanning the development QR.
|
|
1083
|
+
const revision = `${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
1084
|
+
const target = new File(dir, `${safePackageName}.${revision}${extension}`)
|
|
1048
1085
|
const downloaded = await File.downloadFileAsync(iconUrl, target, {idempotent: true})
|
|
1049
1086
|
|
|
1050
1087
|
// Only remove older extensions AFTER the replacement is safely on disk;
|
|
@@ -1174,8 +1211,7 @@ export async function registerDevApp(record: DevAppRecord): Promise<DevAppRecord
|
|
|
1174
1211
|
// Relaunch paths (developer-URL screen, loadDevMiniapp) omit mdnsHost, so an
|
|
1175
1212
|
// omitted field keeps whatever the QR scan stored instead of wiping the
|
|
1176
1213
|
// `.local` failover host.
|
|
1177
|
-
const mdnsHost =
|
|
1178
|
-
record.mdnsHost !== undefined ? record.mdnsHost.trim() || undefined : readStoredMdnsHost(packageName)
|
|
1214
|
+
const mdnsHost = record.mdnsHost !== undefined ? record.mdnsHost.trim() || undefined : readStoredMdnsHost(packageName)
|
|
1179
1215
|
const devRecord: DevAppRecord = {
|
|
1180
1216
|
...record,
|
|
1181
1217
|
packageName,
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - `share` hands a stored file to the OS share sheet.
|
|
16
16
|
*
|
|
17
17
|
* Layout (mirrors SimpleStorage's scoping):
|
|
18
|
-
* bytes: Paths.document/
|
|
18
|
+
* bytes: Paths.document/blobs/{userId}/{packageName}/{fileName}
|
|
19
19
|
* metadata: MMKV key glassly_blobmeta_{userId}_{packageName}_{key} → StoredBlobMeta JSON
|
|
20
20
|
*
|
|
21
21
|
* The on-disk file name is a generated id plus a mime-derived extension (iOS
|
|
@@ -39,7 +39,7 @@ const LOG_TAG = "LocalMiniappRuntime"
|
|
|
39
39
|
|
|
40
40
|
/** Per-app blob quota: 1 GB. */
|
|
41
41
|
export const BLOB_QUOTA_BYTES = 1024 * 1024 * 1024
|
|
42
|
-
const ROOT_DIR_NAME = "
|
|
42
|
+
const ROOT_DIR_NAME = "blobs"
|
|
43
43
|
/** Cache dir root holding short-lived, properly-named copies handed to the OS share sheet (one subdir per stored blob). */
|
|
44
44
|
const SHARE_DIR_NAME = "blob_share"
|
|
45
45
|
/**
|
|
@@ -115,7 +115,7 @@ export class BlobStore {
|
|
|
115
115
|
* Move blob *bytes* from a device-local user directory into the account's on
|
|
116
116
|
* first sign-in. The matching metadata keys are moved by
|
|
117
117
|
* migrateLocalMiniappData(); this half owns the filesystem because the path
|
|
118
|
-
* scheme (`
|
|
118
|
+
* scheme (`blobs/{userId}/{pkg}/`) is private to BlobStore.
|
|
119
119
|
*
|
|
120
120
|
* Per-package so an account directory that already exists wins for that
|
|
121
121
|
* package only — mirroring the key-level "account data wins" rule instead of
|
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
* this service.
|
|
15
15
|
*/
|
|
16
16
|
import {CloudClient, setNativeHttp, setNativeUdp, setSecureStorage} from "@glassly/cloud-client/react-native"
|
|
17
|
-
import type {
|
|
17
|
+
import type {
|
|
18
|
+
PreinstalledMiniappRegistry,
|
|
19
|
+
RuntimeSnapshot,
|
|
20
|
+
StoreCatalogResponse,
|
|
21
|
+
StoreListing,
|
|
22
|
+
} from "@glassly/cloud-client/react-native"
|
|
18
23
|
import type {SubjectTokenType} from "@glassly/cloud-client"
|
|
19
24
|
import {Platform} from "react-native"
|
|
20
25
|
import type {AudioSubscription, QuotaStatusPayload, TranscriptionData, TranslationData} from "@glassly/cloud-protocol"
|
|
@@ -206,8 +211,8 @@ async function syncCoreAccessTokenToBluetoothInternal(): Promise<string> {
|
|
|
206
211
|
if (c !== client) {
|
|
207
212
|
throw new Error("cloud client changed while syncing core token")
|
|
208
213
|
}
|
|
209
|
-
adoptLocalNamespace(c.auth.identity.
|
|
210
|
-
localMiniappUserIdentity.remember(c.auth.identity.
|
|
214
|
+
adoptLocalNamespace(c.auth.identity.userId)
|
|
215
|
+
localMiniappUserIdentity.remember(c.auth.identity.userId)
|
|
211
216
|
const result = await useSettingsStore.getState().setSetting(SETTINGS.core_token.key, token, false)
|
|
212
217
|
if (result.is_error()) {
|
|
213
218
|
throw result.error
|
|
@@ -380,7 +385,7 @@ function ensureAuthWatch(): void {
|
|
|
380
385
|
try {
|
|
381
386
|
cloudClientService.reconnect()
|
|
382
387
|
} finally {
|
|
383
|
-
setTimeout(() => {
|
|
388
|
+
BgTimer.setTimeout(() => {
|
|
384
389
|
reconnectPending = false
|
|
385
390
|
}, 0)
|
|
386
391
|
}
|
|
@@ -734,6 +739,28 @@ export const cloudClientService = {
|
|
|
734
739
|
return c.core.miniapps.getRegistry()
|
|
735
740
|
},
|
|
736
741
|
|
|
742
|
+
async getStoreCatalog(): Promise<StoreCatalogResponse> {
|
|
743
|
+
if (!client) this.init()
|
|
744
|
+
const c = client
|
|
745
|
+
if (!c?.core) throw new Error("cloud client core is unavailable")
|
|
746
|
+
return c.core.store.list()
|
|
747
|
+
},
|
|
748
|
+
|
|
749
|
+
async getStoreListing(packageName: string): Promise<StoreListing> {
|
|
750
|
+
if (!client) this.init()
|
|
751
|
+
const c = client
|
|
752
|
+
if (!c?.core) throw new Error("cloud client core is unavailable")
|
|
753
|
+
return c.core.store.get(packageName)
|
|
754
|
+
},
|
|
755
|
+
|
|
756
|
+
/** Bytes of a store icon or screenshot; these routes need the user Bearer. */
|
|
757
|
+
async fetchStoreAsset(url: string): Promise<Uint8Array> {
|
|
758
|
+
if (!client) this.init()
|
|
759
|
+
const c = client
|
|
760
|
+
if (!c?.core) throw new Error("cloud client core is unavailable")
|
|
761
|
+
return c.core.store.fetchAsset(url)
|
|
762
|
+
},
|
|
763
|
+
|
|
737
764
|
/**
|
|
738
765
|
* Resolve the stable Core-owned Glassly user id.
|
|
739
766
|
*
|
|
@@ -743,7 +770,7 @@ export const cloudClientService = {
|
|
|
743
770
|
* callers join the auth module's single-flight exchange/refresh instead of
|
|
744
771
|
* falling back to an anonymous namespace.
|
|
745
772
|
*/
|
|
746
|
-
async
|
|
773
|
+
async resolveUserId(): Promise<string> {
|
|
747
774
|
// With cloud off there is no client to exchange a token with and never will
|
|
748
775
|
// be, so the online path below would throw on every storage call and take
|
|
749
776
|
// offline-capable local miniapps down with it. Fall back to a device-local
|
|
@@ -759,14 +786,14 @@ export const cloudClientService = {
|
|
|
759
786
|
if (c !== client) throw new Error("cloud client changed while resolving user identity")
|
|
760
787
|
// Runs before resolve() persists the id, so the local namespace is adopted
|
|
761
788
|
// whichever path reaches Core identity first (this or the token sync).
|
|
762
|
-
adoptLocalNamespace(c.auth.identity.
|
|
763
|
-
return c.auth.identity.
|
|
789
|
+
adoptLocalNamespace(c.auth.identity.userId)
|
|
790
|
+
return c.auth.identity.userId
|
|
764
791
|
})
|
|
765
792
|
},
|
|
766
793
|
|
|
767
794
|
/** Read the stable Glassly user id after async identity resolution. */
|
|
768
|
-
|
|
769
|
-
// Mirrors
|
|
795
|
+
getUserId(): string {
|
|
796
|
+
// Mirrors resolveUserId(): with cloud off, minting is synchronous and
|
|
770
797
|
// cannot fail, so sync callers (BlobStore) don't depend on an async resolve
|
|
771
798
|
// having run first.
|
|
772
799
|
if (cloudDisabled()) return localMiniappUserIdentity.resolveLocal()
|
|
@@ -786,7 +813,7 @@ export const cloudClientService = {
|
|
|
786
813
|
const {token, expiresAt} = await c.auth.getMiniappToken(packageName, opts)
|
|
787
814
|
const identity = c.auth.identity
|
|
788
815
|
return {
|
|
789
|
-
|
|
816
|
+
userId: identity.userId,
|
|
790
817
|
tenantId: identity.tenantId,
|
|
791
818
|
token,
|
|
792
819
|
expiresAt: normalizeExpiresAt(expiresAt),
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import {BgTimer} from "../utils/timers"
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* DevServerBridge — phone-side WebSocket connection to a `glassly-miniapp dev`
|
|
3
5
|
* sidecar running on a developer's laptop.
|
|
@@ -44,7 +46,7 @@ interface BridgeEntry {
|
|
|
44
46
|
ringBuffer: BufferedLog[]
|
|
45
47
|
ringBytes: number
|
|
46
48
|
reloadHandler: ((packageName: string) => void) | null
|
|
47
|
-
reconnectTimer:
|
|
49
|
+
reconnectTimer: number | null
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
class DevServerBridge {
|
|
@@ -116,7 +118,7 @@ class DevServerBridge {
|
|
|
116
118
|
* side (`UIRouter.routeFromWebView` for `type:"log"` frames).
|
|
117
119
|
*
|
|
118
120
|
* `source` distinguishes the two halves so the CLI can prefix lines
|
|
119
|
-
* `[UI]` vs `[
|
|
121
|
+
* `[UI]` vs `[JSRuntime]`. Logs are silently dropped when no bridge
|
|
120
122
|
* exists for the package (no `glassly-miniapp dev` running) and
|
|
121
123
|
* buffered in the per-bridge ring while disconnected.
|
|
122
124
|
*/
|
|
@@ -155,7 +157,7 @@ class DevServerBridge {
|
|
|
155
157
|
.split(":")[0]
|
|
156
158
|
.split("/")[0]
|
|
157
159
|
}
|
|
158
|
-
return `ws://${host}:${devPort}/
|
|
160
|
+
return `ws://${host}:${devPort}/__host_dev`
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
private openSocket(packageName: string, entry: BridgeEntry): void {
|
|
@@ -164,12 +166,12 @@ class DevServerBridge {
|
|
|
164
166
|
const ws = new WebSocket(entry.url)
|
|
165
167
|
entry.ws = ws
|
|
166
168
|
|
|
167
|
-
let helloTimer:
|
|
169
|
+
let helloTimer: number | null = null
|
|
168
170
|
let helloAcked = false
|
|
169
171
|
|
|
170
172
|
const teardown = (reason: string): void => {
|
|
171
173
|
if (helloTimer) {
|
|
172
|
-
clearTimeout(helloTimer)
|
|
174
|
+
BgTimer.clearTimeout(helloTimer)
|
|
173
175
|
helloTimer = null
|
|
174
176
|
}
|
|
175
177
|
try {
|
|
@@ -195,7 +197,7 @@ class DevServerBridge {
|
|
|
195
197
|
teardown("hello send failed")
|
|
196
198
|
return
|
|
197
199
|
}
|
|
198
|
-
helloTimer = setTimeout(() => {
|
|
200
|
+
helloTimer = BgTimer.setTimeout(() => {
|
|
199
201
|
if (!helloAcked) {
|
|
200
202
|
teardown("hello-ack timeout")
|
|
201
203
|
}
|
|
@@ -220,7 +222,7 @@ class DevServerBridge {
|
|
|
220
222
|
}
|
|
221
223
|
helloAcked = true
|
|
222
224
|
if (helloTimer) {
|
|
223
|
-
clearTimeout(helloTimer)
|
|
225
|
+
BgTimer.clearTimeout(helloTimer)
|
|
224
226
|
helloTimer = null
|
|
225
227
|
}
|
|
226
228
|
entry.state = "connected"
|
|
@@ -257,9 +259,9 @@ class DevServerBridge {
|
|
|
257
259
|
|
|
258
260
|
private scheduleReconnect(packageName: string, entry: BridgeEntry): void {
|
|
259
261
|
if (entry.state === "closed") return
|
|
260
|
-
if (entry.reconnectTimer) clearTimeout(entry.reconnectTimer)
|
|
262
|
+
if (entry.reconnectTimer) BgTimer.clearTimeout(entry.reconnectTimer)
|
|
261
263
|
const delay = this.backoffMs(entry.attempts)
|
|
262
|
-
entry.reconnectTimer = setTimeout(() => {
|
|
264
|
+
entry.reconnectTimer = BgTimer.setTimeout(() => {
|
|
263
265
|
entry.reconnectTimer = null
|
|
264
266
|
// Verify still alive and still in the bridge map.
|
|
265
267
|
const current = this.entries.get(packageName)
|
|
@@ -316,7 +318,7 @@ class DevServerBridge {
|
|
|
316
318
|
|
|
317
319
|
private teardownEntry(entry: BridgeEntry): void {
|
|
318
320
|
if (entry.reconnectTimer) {
|
|
319
|
-
clearTimeout(entry.reconnectTimer)
|
|
321
|
+
BgTimer.clearTimeout(entry.reconnectTimer)
|
|
320
322
|
entry.reconnectTimer = null
|
|
321
323
|
}
|
|
322
324
|
if (entry.ws) {
|