@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
|
@@ -58,7 +58,7 @@ export class HardwareCompatibility {
|
|
|
58
58
|
case HardwareType.DISPLAY:
|
|
59
59
|
return capabilities.hasDisplay;
|
|
60
60
|
case HardwareType.MICROPHONE:
|
|
61
|
-
//
|
|
61
|
+
// Glassly always provides an audio-input path. When the connected
|
|
62
62
|
// glasses do not have an onboard microphone, the engine falls back to
|
|
63
63
|
// the phone microphone. Keep `capabilities.hasMicrophone` reserved for
|
|
64
64
|
// physical-device/source selection; app compatibility is about whether
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../../src/utils/hardware/hardware.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,YAAY,EACZ,wBAAwB,EACxB,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAA;AAYpB;;GAEG;AACH,MAAM,OAAO,qBAAqB;IAChC;;;;;OAKG;IACH,MAAM,CAAC,kBAAkB,CACvB,oBAA2C,EAC3C,YAAiC;QAEjC,MAAM,MAAM,GAAwB;YAClC,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,EAAE;YACnB,eAAe,EAAE,EAAE;YACnB,QAAQ,EAAE,EAAE;SACb,CAAA;QAED,6EAA6E;QAC7E,IAAI,oBAAoB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,OAAO,MAAM,CAAA;QACf,CAAC;QAED,yDAAyD;QACzD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,YAAY,GAAG,gBAAgB,CAAA;QACjC,CAAC;QAED,kCAAkC;QAClC,KAAK,MAAM,WAAW,IAAI,oBAAoB,EAAE,CAAC;YAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,IAAI,EAAE,YAAa,CAAC,CAAA;YAChF,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,IAAI,WAAW,CAAC,KAAK,KAAK,wBAAwB,CAAC,QAAQ,EAAE,CAAC;oBAC5D,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;oBACxC,MAAM,CAAC,YAAY,GAAG,KAAK,CAAA;gBAC7B,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;gBAC1C,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAED;;;;;OAKG;IACK,MAAM,CAAC,sBAAsB,CAAC,YAA0B,EAAE,YAA0B;QAC1F,IAAI,YAAY,KAAK,YAAY,CAAC,KAAK,EAAE,CAAC;YACxC,IAAI,YAAY,CAAC,SAAS,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;gBAChD,OAAO,KAAK,CAAA;YACd,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QAED,QAAQ,YAAY,EAAE,CAAC;YACrB,KAAK,YAAY,CAAC,MAAM;gBACtB,OAAO,YAAY,CAAC,SAAS,CAAA;YAE/B,KAAK,YAAY,CAAC,OAAO;gBACvB,OAAO,YAAY,CAAC,UAAU,CAAA;YAEhC,KAAK,YAAY,CAAC,UAAU;gBAC1B,
|
|
1
|
+
{"version":3,"file":"hardware.js","sourceRoot":"","sources":["../../../src/utils/hardware/hardware.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Capabilities,\n HardwareRequirement,\n HardwareType,\n HardwareRequirementLevel,\n DeviceTypes,\n simulatedGlasses,\n} from \"../../types\"\n\n/**\n * Result of a hardware compatibility check\n */\nexport interface CompatibilityResult {\n isCompatible: boolean\n missingRequired: HardwareRequirement[]\n missingOptional: HardwareRequirement[]\n warnings: string[]\n}\n\n/**\n * Service for checking hardware compatibility between apps and glasses\n */\nexport class HardwareCompatibility {\n /**\n * Check if app is compatible with given device capabilities\n * @param app The app to check\n * @param capabilities The device capabilities (null if no device connected)\n * @returns Detailed compatibility result\n */\n static checkCompatibility(\n hardwareRequirements: HardwareRequirement[],\n capabilities: Capabilities | null,\n ): CompatibilityResult {\n const result: CompatibilityResult = {\n isCompatible: true,\n missingRequired: [],\n missingOptional: [],\n warnings: [],\n }\n\n // If no hardware requirements specified, app is compatible with any hardware\n if (hardwareRequirements.length === 0) {\n return result\n }\n\n // If no capabilities available assume simulated glasses:\n if (!capabilities) {\n capabilities = simulatedGlasses\n }\n\n // Check each hardware requirement\n for (const requirement of hardwareRequirements) {\n const hasHardware = this.checkHardwareAvailable(requirement.type, capabilities!)\n if (!hasHardware) {\n if (requirement.level === HardwareRequirementLevel.REQUIRED) {\n result.missingRequired.push(requirement)\n result.isCompatible = false\n } else {\n result.missingOptional.push(requirement)\n }\n }\n }\n\n return result\n }\n\n /**\n * Check if specific hardware is available in capabilities\n * @param hardwareType The type of hardware to check\n * @param capabilities The device capabilities\n * @returns true if hardware is available\n */\n private static checkHardwareAvailable(hardwareType: HardwareType, capabilities: Capabilities): boolean {\n if (hardwareType === HardwareType.EXIST) {\n if (capabilities.modelName === DeviceTypes.NONE) {\n return false\n }\n return true\n }\n\n switch (hardwareType) {\n case HardwareType.CAMERA:\n return capabilities.hasCamera\n\n case HardwareType.DISPLAY:\n return capabilities.hasDisplay\n\n case HardwareType.MICROPHONE:\n // Glassly always provides an audio-input path. When the connected\n // glasses do not have an onboard microphone, the engine falls back to\n // the phone microphone. Keep `capabilities.hasMicrophone` reserved for\n // physical-device/source selection; app compatibility is about whether\n // the requested input is available to the miniapp.\n return true\n\n case HardwareType.SPEAKER:\n return capabilities.hasSpeaker\n\n case HardwareType.IMU:\n return capabilities.hasIMU\n\n case HardwareType.BUTTON:\n return capabilities.hasButton\n\n case HardwareType.LIGHT:\n return capabilities.hasLight\n\n case HardwareType.WIFI:\n return capabilities.hasWifi\n\n default:\n // Unknown hardware type - assume not available\n return false\n }\n }\n\n /**\n * Get human-readable compatibility message\n * @param result The compatibility check result\n * @returns User-friendly message about compatibility\n */\n static getCompatibilityMessage(result: CompatibilityResult): string {\n if (result.isCompatible) {\n if (result.missingOptional.length > 0) {\n const optionalHardware = result.missingOptional.map((req) => req.type.toLowerCase()).join(\", \")\n return `This app works with your glasses but has optional features that require: ${optionalHardware}`\n }\n return \"This app is fully compatible with your glasses\"\n }\n\n const requiredHardware = result.missingRequired.map((req) => req.type.toLowerCase()).join(\", \")\n\n if (result.missingRequired.length === 1) {\n return `This app requires a ${requiredHardware} which is not available on your connected glasses`\n } else {\n return `This app requires the following hardware which is not available on your connected glasses: ${requiredHardware}`\n }\n }\n\n /**\n * Get detailed compatibility messages including descriptions\n * @param result The compatibility check result\n * @returns Array of detailed messages\n */\n static getDetailedMessages(result: CompatibilityResult): string[] {\n const messages: string[] = []\n\n // Add warnings first\n messages.push(...result.warnings)\n\n // Add missing required hardware\n for (const req of result.missingRequired) {\n let message = `❌ Missing required ${req.type.toLowerCase()}`\n if (req.description) {\n message += `: ${req.description}`\n }\n messages.push(message)\n }\n\n // Add missing optional hardware\n for (const req of result.missingOptional) {\n let message = `⚠️ Missing optional ${req.type.toLowerCase()}`\n if (req.description) {\n message += `: ${req.description}`\n }\n messages.push(message)\n }\n\n return messages\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timers.d.ts","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"AAoJA,qBAAa,OAAO;IAClB,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO/D,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAO9C,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAO9D,MAAM,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAM7C;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAU/G;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAY/G"}
|
|
@@ -21,7 +21,29 @@
|
|
|
21
21
|
// https://github.com/tconns/react-native-nitro-bg-timer/issues/2. iOS
|
|
22
22
|
// suspends the whole process in background anyway, so background timing
|
|
23
23
|
// there is handled by native per-device queues, not JS timers.
|
|
24
|
-
|
|
24
|
+
//
|
|
25
|
+
// react-native is loaded lazily, not imported. Every engine service runs its
|
|
26
|
+
// timers through this module, and the engine's bun test suites load those
|
|
27
|
+
// services in a plain JS runtime that cannot parse react-native's Flow
|
|
28
|
+
// source. A static import would force every such suite to mock this module;
|
|
29
|
+
// with the lazy load, a runtime without react-native simply gets the JS
|
|
30
|
+
// timers, which is the correct answer there anyway.
|
|
31
|
+
let reactNative;
|
|
32
|
+
function getReactNative() {
|
|
33
|
+
if (reactNative !== undefined) {
|
|
34
|
+
return reactNative;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
reactNative = require("react-native");
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
reactNative = null;
|
|
41
|
+
}
|
|
42
|
+
return reactNative;
|
|
43
|
+
}
|
|
44
|
+
function isDev() {
|
|
45
|
+
return typeof __DEV__ !== "undefined" && __DEV__;
|
|
46
|
+
}
|
|
25
47
|
let nitroTimer;
|
|
26
48
|
let nitroDisabled = false;
|
|
27
49
|
let failedLoud = false;
|
|
@@ -42,12 +64,12 @@ function failUnavailable(reason) {
|
|
|
42
64
|
"Backgrounded behavior IS BROKEN until you rebuild the Android app: run `bun android`. " +
|
|
43
65
|
"Engine timers and local miniapps (captions, wake words) freeze whenever the app is not foregrounded.";
|
|
44
66
|
console.error(message);
|
|
45
|
-
if (
|
|
67
|
+
if (isDev()) {
|
|
46
68
|
// A stale dev client may ALSO show the library's own require-time red box
|
|
47
69
|
// (bridgeless LogBox surfaces it even though we catch below) — this alert
|
|
48
70
|
// is the actionable one: it names the fix.
|
|
49
71
|
try {
|
|
50
|
-
Alert
|
|
72
|
+
getReactNative()?.Alert?.alert("Background timers unavailable", message);
|
|
51
73
|
}
|
|
52
74
|
catch {
|
|
53
75
|
/* Alert not available (tests / headless) — the console.error stands. */
|
|
@@ -55,7 +77,7 @@ function failUnavailable(reason) {
|
|
|
55
77
|
}
|
|
56
78
|
}
|
|
57
79
|
function getNitroTimer() {
|
|
58
|
-
if (nitroDisabled || Platform.OS !== "android") {
|
|
80
|
+
if (nitroDisabled || getReactNative()?.Platform.OS !== "android") {
|
|
59
81
|
return null;
|
|
60
82
|
}
|
|
61
83
|
if (nitroTimer !== undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timers.js","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"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","sourcesContent":["// BgTimer — background-safe timers for the engine.\n//\n// Everything timing-critical in the engine runs through this class: the\n// miniapp liveness watchdog, display durationMs expiries, boot windows,\n// auth-token refresh. On Android, React Native PAUSES plain JS timers while\n// the app is backgrounded, so those features only keep working in the\n// background when the native implementation (react-native-nitro-bg-timer)\n// is active.\n//\n// Who actually gets native timers:\n// - Android, dev AND release: always attempted — dev must match production\n// background behavior. There is no opt-in/opt-out env var. If the native\n// module is unavailable (a dev client whose binary predates it, or a\n// broken release binary), the failure is LOUD: a console.error with the\n// remediation, plus a blocking dev alert. The JS-timer fallback still\n// engages so foreground behavior keeps working, but backgrounded\n// behavior is broken until the native rebuild — the error says exactly\n// that. (A silent dev fallback previously cost a full debugging day of\n// phantom \"zombie miniapp\" bugs; see OS-1790.)\n// - iOS: never, dev or prod — the package is disabled pending\n// https://github.com/tconns/react-native-nitro-bg-timer/issues/2. iOS\n// suspends the whole process in background anyway, so background timing\n// there is handled by native per-device queues, not JS timers.\n\nimport {Alert, Platform} from \"react-native\"\n\ntype NitroTimerApi = {\n setInterval: (callback: () => void, delay: number) => number\n clearInterval: (intervalId: number) => void\n setTimeout: (callback: () => void, delay: number) => number\n clearTimeout: (timeoutId: number) => void\n}\n\nlet nitroTimer: NitroTimerApi | null | undefined\nlet nitroDisabled = false\nlet failedLoud = false\n\n/**\n * The native background timer is unavailable — say so ONCE, loudly, with the\n * remediation. The JS-timer fallback keeps foreground behavior working, but\n * everything timing-driven freezes while the app is backgrounded, which\n * presents as phantom miniapp bugs (frozen captions, missed wake words,\n * watchdog kills on resume). A quiet warning here has already cost a full\n * debugging day; never downgrade this to console.warn.\n */\nfunction failUnavailable(reason: string) {\n if (failedLoud) {\n return\n }\n failedLoud = true\n const message =\n `BgTimer: native background timer unavailable (${reason}). ` +\n \"Backgrounded behavior IS BROKEN until you rebuild the Android app: run `bun android`. \" +\n \"Engine timers and local miniapps (captions, wake words) freeze whenever the app is not foregrounded.\"\n console.error(message)\n if (__DEV__) {\n // A stale dev client may ALSO show the library's own require-time red box\n // (bridgeless LogBox surfaces it even though we catch below) — this alert\n // is the actionable one: it names the fix.\n try {\n Alert.alert(\"Background timers unavailable\", message)\n } catch {\n /* Alert not available (tests / headless) — the console.error stands. */\n }\n }\n}\n\nfunction getNitroTimer(): NitroTimerApi | null {\n if (nitroDisabled || Platform.OS !== \"android\") {\n return null\n }\n\n if (nitroTimer !== undefined) {\n return nitroTimer\n }\n\n try {\n const {isRuntimeAlive} = require(\"react-native-nitro-modules\") as {isRuntimeAlive?: () => boolean}\n if (typeof isRuntimeAlive === \"function\" && !isRuntimeAlive()) {\n nitroTimer = null\n failUnavailable(\"nitro runtime is not alive\")\n return nitroTimer\n }\n\n const {BackgroundTimer} = require(\"react-native-nitro-bg-timer\") as {BackgroundTimer?: NitroTimerApi}\n nitroTimer =\n BackgroundTimer &&\n typeof BackgroundTimer.setTimeout === \"function\" &&\n typeof BackgroundTimer.setInterval === \"function\" &&\n typeof BackgroundTimer.clearTimeout === \"function\" &&\n typeof BackgroundTimer.clearInterval === \"function\"\n ? BackgroundTimer\n : null\n } catch {\n nitroTimer = null\n nitroDisabled = true\n }\n\n if (!nitroTimer) {\n failUnavailable(\"react-native-nitro-bg-timer failed to load\")\n }\n return nitroTimer\n}\n\nfunction withNitro<T>(run: (api: NitroTimerApi) => T, fallback: () => T): T {\n const api = getNitroTimer()\n if (!api) {\n return fallback()\n }\n try {\n return run(api)\n } catch (error) {\n nitroDisabled = true\n nitroTimer = null\n failedLoud = false // a mid-session failure is new information — re-announce\n failUnavailable(`nitro timer call threw: ${String(error)}`)\n return fallback()\n }\n}\n\nexport class BgTimer {\n static setInterval(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setInterval(callback, delay),\n () => setInterval(callback, delay) as unknown as number,\n )\n }\n\n static clearInterval(intervalId: number): void {\n withNitro(\n (api) => api.clearInterval(intervalId),\n () => clearInterval(intervalId),\n )\n }\n\n static setTimeout(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setTimeout(callback, delay),\n () => setTimeout(callback, delay) as unknown as number,\n )\n }\n\n static clearTimeout(timeoutId: number): void {\n withNitro(\n (api) => api.clearTimeout(timeoutId),\n () => clearTimeout(timeoutId),\n )\n }\n}\n\nexport function throttle<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let lastCalled = 0\n\n return (...args: Parameters<T>) => {\n const now = Date.now()\n if (now - lastCalled >= ms) {\n lastCalled = now\n fn(...args)\n }\n }\n}\n\nexport function debounce<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let timeoutId: number | null = null\n\n return (...args: Parameters<T>) => {\n if (timeoutId) {\n BgTimer.clearTimeout(timeoutId)\n }\n timeoutId = BgTimer.setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, ms)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"timers.js","sourceRoot":"","sources":["../../../src/utils/timers/timers.ts"],"names":[],"mappings":"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","sourcesContent":["// BgTimer — background-safe timers for the engine.\n//\n// Everything timing-critical in the engine runs through this class: the\n// miniapp liveness watchdog, display durationMs expiries, boot windows,\n// auth-token refresh. On Android, React Native PAUSES plain JS timers while\n// the app is backgrounded, so those features only keep working in the\n// background when the native implementation (react-native-nitro-bg-timer)\n// is active.\n//\n// Who actually gets native timers:\n// - Android, dev AND release: always attempted — dev must match production\n// background behavior. There is no opt-in/opt-out env var. If the native\n// module is unavailable (a dev client whose binary predates it, or a\n// broken release binary), the failure is LOUD: a console.error with the\n// remediation, plus a blocking dev alert. The JS-timer fallback still\n// engages so foreground behavior keeps working, but backgrounded\n// behavior is broken until the native rebuild — the error says exactly\n// that. (A silent dev fallback previously cost a full debugging day of\n// phantom \"zombie miniapp\" bugs; see OS-1790.)\n// - iOS: never, dev or prod — the package is disabled pending\n// https://github.com/tconns/react-native-nitro-bg-timer/issues/2. iOS\n// suspends the whole process in background anyway, so background timing\n// there is handled by native per-device queues, not JS timers.\n//\n// react-native is loaded lazily, not imported. Every engine service runs its\n// timers through this module, and the engine's bun test suites load those\n// services in a plain JS runtime that cannot parse react-native's Flow\n// source. A static import would force every such suite to mock this module;\n// with the lazy load, a runtime without react-native simply gets the JS\n// timers, which is the correct answer there anyway.\n\ntype ReactNativeSubset = {\n Platform: {OS: string}\n Alert?: {alert: (title: string, message?: string) => void}\n}\n\nlet reactNative: ReactNativeSubset | null | undefined\n\nfunction getReactNative(): ReactNativeSubset | null {\n if (reactNative !== undefined) {\n return reactNative\n }\n try {\n reactNative = require(\"react-native\") as ReactNativeSubset\n } catch {\n reactNative = null\n }\n return reactNative\n}\n\nfunction isDev(): boolean {\n return typeof __DEV__ !== \"undefined\" && __DEV__\n}\n\ntype NitroTimerApi = {\n setInterval: (callback: () => void, delay: number) => number\n clearInterval: (intervalId: number) => void\n setTimeout: (callback: () => void, delay: number) => number\n clearTimeout: (timeoutId: number) => void\n}\n\nlet nitroTimer: NitroTimerApi | null | undefined\nlet nitroDisabled = false\nlet failedLoud = false\n\n/**\n * The native background timer is unavailable — say so ONCE, loudly, with the\n * remediation. The JS-timer fallback keeps foreground behavior working, but\n * everything timing-driven freezes while the app is backgrounded, which\n * presents as phantom miniapp bugs (frozen captions, missed wake words,\n * watchdog kills on resume). A quiet warning here has already cost a full\n * debugging day; never downgrade this to console.warn.\n */\nfunction failUnavailable(reason: string) {\n if (failedLoud) {\n return\n }\n failedLoud = true\n const message =\n `BgTimer: native background timer unavailable (${reason}). ` +\n \"Backgrounded behavior IS BROKEN until you rebuild the Android app: run `bun android`. \" +\n \"Engine timers and local miniapps (captions, wake words) freeze whenever the app is not foregrounded.\"\n console.error(message)\n if (isDev()) {\n // A stale dev client may ALSO show the library's own require-time red box\n // (bridgeless LogBox surfaces it even though we catch below) — this alert\n // is the actionable one: it names the fix.\n try {\n getReactNative()?.Alert?.alert(\"Background timers unavailable\", message)\n } catch {\n /* Alert not available (tests / headless) — the console.error stands. */\n }\n }\n}\n\nfunction getNitroTimer(): NitroTimerApi | null {\n if (nitroDisabled || getReactNative()?.Platform.OS !== \"android\") {\n return null\n }\n\n if (nitroTimer !== undefined) {\n return nitroTimer\n }\n\n try {\n const {isRuntimeAlive} = require(\"react-native-nitro-modules\") as {isRuntimeAlive?: () => boolean}\n if (typeof isRuntimeAlive === \"function\" && !isRuntimeAlive()) {\n nitroTimer = null\n failUnavailable(\"nitro runtime is not alive\")\n return nitroTimer\n }\n\n const {BackgroundTimer} = require(\"react-native-nitro-bg-timer\") as {BackgroundTimer?: NitroTimerApi}\n nitroTimer =\n BackgroundTimer &&\n typeof BackgroundTimer.setTimeout === \"function\" &&\n typeof BackgroundTimer.setInterval === \"function\" &&\n typeof BackgroundTimer.clearTimeout === \"function\" &&\n typeof BackgroundTimer.clearInterval === \"function\"\n ? BackgroundTimer\n : null\n } catch {\n nitroTimer = null\n nitroDisabled = true\n }\n\n if (!nitroTimer) {\n failUnavailable(\"react-native-nitro-bg-timer failed to load\")\n }\n return nitroTimer\n}\n\nfunction withNitro<T>(run: (api: NitroTimerApi) => T, fallback: () => T): T {\n const api = getNitroTimer()\n if (!api) {\n return fallback()\n }\n try {\n return run(api)\n } catch (error) {\n nitroDisabled = true\n nitroTimer = null\n failedLoud = false // a mid-session failure is new information — re-announce\n failUnavailable(`nitro timer call threw: ${String(error)}`)\n return fallback()\n }\n}\n\nexport class BgTimer {\n static setInterval(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setInterval(callback, delay),\n () => setInterval(callback, delay) as unknown as number,\n )\n }\n\n static clearInterval(intervalId: number): void {\n withNitro(\n (api) => api.clearInterval(intervalId),\n () => clearInterval(intervalId),\n )\n }\n\n static setTimeout(callback: () => void, delay: number): number {\n return withNitro(\n (api) => api.setTimeout(callback, delay),\n () => setTimeout(callback, delay) as unknown as number,\n )\n }\n\n static clearTimeout(timeoutId: number): void {\n withNitro(\n (api) => api.clearTimeout(timeoutId),\n () => clearTimeout(timeoutId),\n )\n }\n}\n\nexport function throttle<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let lastCalled = 0\n\n return (...args: Parameters<T>) => {\n const now = Date.now()\n if (now - lastCalled >= ms) {\n lastCalled = now\n fn(...args)\n }\n }\n}\n\nexport function debounce<T extends (...args: any[]) => any>(fn: T, ms: number): (...args: Parameters<T>) => void {\n let timeoutId: number | null = null\n\n return (...args: Parameters<T>) => {\n if (timeoutId) {\n BgTimer.clearTimeout(timeoutId)\n }\n timeoutId = BgTimer.setTimeout(() => {\n fn(...args)\n timeoutId = null\n }, ms)\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glassly/engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.9-beta.448",
|
|
4
4
|
"description": "Glassly Engine — miniapp registry, WebView bridge, and miniapp store",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -97,23 +97,23 @@
|
|
|
97
97
|
"registry": "https://registry.npmjs.org/"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
|
-
"@glassly/bluetooth-sdk": "0.
|
|
101
|
-
"@glassly/cloud-client": "0.
|
|
102
|
-
"@glassly/cloud-protocol": "0.
|
|
103
|
-
"@glassly/crust": "0.
|
|
104
|
-
"@glassly/miniapp": "0.
|
|
100
|
+
"@glassly/bluetooth-sdk": "0.2.9-beta.448",
|
|
101
|
+
"@glassly/cloud-client": "0.2.9-beta.448",
|
|
102
|
+
"@glassly/cloud-protocol": "0.2.9-beta.448",
|
|
103
|
+
"@glassly/crust": "0.2.9-beta.448",
|
|
104
|
+
"@glassly/miniapp": "0.2.9-beta.448",
|
|
105
105
|
"buffer": "^6.0.3",
|
|
106
106
|
"events": "^3.3.0",
|
|
107
107
|
"react-native-marked": "8.1.1",
|
|
108
108
|
"semver": "^7.7.4",
|
|
109
109
|
"typesafe-ts": "^1.7.1",
|
|
110
|
-
"@glassly/llm-providers": "0.
|
|
110
|
+
"@glassly/llm-providers": "0.2.9-beta.448"
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
113
|
"@glassly/llm-providers": "workspace:*",
|
|
114
114
|
"@types/semver": "^7.7.1",
|
|
115
115
|
"expo-module-scripts": "^56.0.3",
|
|
116
|
-
"expo-modules-core": "57.0.7",
|
|
116
|
+
"expo-modules-core": "^57.0.7",
|
|
117
117
|
"react-native-nitro-modules": "^0.31.10",
|
|
118
118
|
"typescript": "~5.9.2"
|
|
119
119
|
},
|
package/src/engine.ts
CHANGED
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
* name stays `engine` in code; the public API surface is `engine`.)
|
|
6
6
|
*
|
|
7
7
|
* It grows one facade at a time. The migration-era flat store/service exports
|
|
8
|
-
* remain in a private
|
|
8
|
+
* remain in a private Glassly host package; they shrink as screens move onto
|
|
9
9
|
* `engine.*`.
|
|
10
10
|
*/
|
|
11
11
|
import {configure, start as bootstrapStart, stop as bootstrapStop, updateUiSeams} from "./runtime/bootstrap"
|
|
12
12
|
import {cloudClientService} from "./services/CloudClientService"
|
|
13
13
|
import {hydrateDeviceStore, demoteOrphanedDefaultWearable} from "./services/DeviceStoreHydration"
|
|
14
|
+
import {startPairedGlassesLatch, stopPairedGlassesLatch} from "./services/PairedGlassesLatch"
|
|
14
15
|
import {startGlassesSettingsSync, stopGlassesSettingsSync} from "./services/GlassesSettingsSync"
|
|
15
16
|
import {startGlassesStatusProjection, stopGlassesStatusProjection} from "./services/GlassesStatusProjection"
|
|
16
17
|
import {startOtaService, stopOtaService} from "./services/OtaService"
|
|
@@ -18,6 +19,7 @@ import {startAudioCloudUplink, stopAudioCloudUplink} from "./services/AudioCloud
|
|
|
18
19
|
import sonioxDirectService from "./services/soniox/SonioxDirectService"
|
|
19
20
|
import {startSupportProfileSync, stopSupportProfileSync} from "./services/SupportProfileSync"
|
|
20
21
|
import {startDeviceEventRouter, stopDeviceEventRouter} from "./services/DeviceEventRouter"
|
|
22
|
+
import {startPhoneActivityTracking, stopPhoneActivityTracking} from "./services/PhoneActivity"
|
|
21
23
|
import {startPhoneNotificationsSync, stopPhoneNotificationsSync} from "./services/PhoneNotificationsSync"
|
|
22
24
|
import {startSpeakerIdSync, stopSpeakerIdSync} from "./services/SpeakerIdSync"
|
|
23
25
|
import {startCaptionsTesterReportService, stopCaptionsTesterReportService} from "./services/CaptionsTesterReportService"
|
|
@@ -45,8 +47,7 @@ import {memory} from "./facades/memory"
|
|
|
45
47
|
import {speakers} from "./facades/speakers"
|
|
46
48
|
import {providerKeys} from "./facades/providerKeys"
|
|
47
49
|
import {logBuffer} from "./utils/devLogging"
|
|
48
|
-
import
|
|
49
|
-
import dashboardCoordinator from "./services/DashboardCoordinator"
|
|
50
|
+
import pageHost from "./services/pages/PageHost"
|
|
50
51
|
import gestureDotsService from "./services/GestureDotsService"
|
|
51
52
|
|
|
52
53
|
export const engine = {
|
|
@@ -69,8 +70,12 @@ export const engine = {
|
|
|
69
70
|
// of the runtime reads). Established first so the stores are live before the
|
|
70
71
|
// syncs below react to them.
|
|
71
72
|
startGlassesStatusProjection((changed) => localMiniappRuntime.forwardEvent("glasses_connection_state", changed))
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
// Lock + foreground state, read by the dashboard's notification gate and
|
|
74
|
+
// the G2 notification ctrl below; up before either consumer.
|
|
75
|
+
startPhoneActivityTracking()
|
|
76
|
+
// The overlay slot's owner: the designated dashboard miniapp's page shows
|
|
77
|
+
// through it (ADR-0006), so it is up before the miniapp runtime.
|
|
78
|
+
pageHost.start()
|
|
74
79
|
gestureDotsService.start()
|
|
75
80
|
// Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,
|
|
76
81
|
// photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->
|
|
@@ -95,6 +100,8 @@ export const engine = {
|
|
|
95
100
|
} catch (error) {
|
|
96
101
|
console.warn("engine.start: device-store hydration failed:", error instanceof Error ? error.message : error)
|
|
97
102
|
}
|
|
103
|
+
// After the settings load so an already-paired phone latches on this start.
|
|
104
|
+
startPairedGlassesLatch()
|
|
98
105
|
// Project the glasses' OTA events into the store for the engine.ota read surface.
|
|
99
106
|
startOtaService()
|
|
100
107
|
// Forward glasses mic_lc3 frames to the v2 cloud session so cloud transcription
|
|
@@ -103,14 +110,15 @@ export const engine = {
|
|
|
103
110
|
// Phone -> Soniox direct transcription (user-supplied API key). Started
|
|
104
111
|
// after device-store hydration so the persisted key is already loaded.
|
|
105
112
|
sonioxDirectService.start()
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
// Not awaited: the exchange behind it is a Core round trip with no client
|
|
114
|
+
// deadline, and start() must resolve offline. The glasses get the token
|
|
115
|
+
// when it lands; identity resolution joins the same single-flight exchange.
|
|
116
|
+
void cloudClientService.syncCoreTokenToBluetooth().catch((error) => {
|
|
109
117
|
console.warn(
|
|
110
118
|
"engine.start: initial Cloud V2 core token sync failed:",
|
|
111
119
|
error instanceof Error ? error.message : error,
|
|
112
120
|
)
|
|
113
|
-
}
|
|
121
|
+
})
|
|
114
122
|
startSupportProfileSync()
|
|
115
123
|
// Push device-setting changes to the glasses for ANY host, so
|
|
116
124
|
// engine.glasses.settings.set() reaches the device (not just the Glassly app).
|
|
@@ -124,11 +132,11 @@ export const engine = {
|
|
|
124
132
|
// Android internal/e2e: laptop captions tester can broadcast a failure intent;
|
|
125
133
|
// engine owns turning that into a Cloud V2 report.
|
|
126
134
|
startCaptionsTesterReportService()
|
|
127
|
-
//
|
|
135
|
+
// JSRuntime crashloop-disabled is runtime state; engine owns filing the
|
|
128
136
|
// automatic report while hosts only render alert/telemetry side effects.
|
|
129
137
|
startJSCrashloopReportService()
|
|
130
|
-
// Bring up the local-miniapp engine so a bare OEM can run
|
|
131
|
-
// the LocalMiniappRuntime (registry + WebView bridge), the
|
|
138
|
+
// Bring up the local-miniapp engine so a bare OEM can run JSRuntime miniapps:
|
|
139
|
+
// the LocalMiniappRuntime (registry + WebView bridge), the JSRuntime router
|
|
132
140
|
// (crust-bound spawn/dispatch pump + launcher wiring), the DisplayProcessor
|
|
133
141
|
// (layout arbitration over the engine stores), and the gallery-sync service.
|
|
134
142
|
// All idempotent — when the Glassly app's host bootstrap also calls these, the
|
|
@@ -151,19 +159,20 @@ export const engine = {
|
|
|
151
159
|
}
|
|
152
160
|
}
|
|
153
161
|
await safely("glasses settings sync", stopGlassesSettingsSync)
|
|
162
|
+
await safely("paired glasses latch", stopPairedGlassesLatch)
|
|
154
163
|
await safely("glasses status projection", stopGlassesStatusProjection)
|
|
155
164
|
await safely("device event router", stopDeviceEventRouter)
|
|
156
|
-
await safely("
|
|
157
|
-
await safely("custom dashboard service", () => customDashboardService.stop())
|
|
165
|
+
await safely("page host", () => pageHost.stop())
|
|
158
166
|
await safely("gesture dots service", () => gestureDotsService.stop())
|
|
159
167
|
await safely("ota service", stopOtaService)
|
|
160
168
|
await safely("audio cloud uplink", stopAudioCloudUplink)
|
|
161
169
|
await safely("soniox direct service", () => sonioxDirectService.stop())
|
|
162
170
|
await safely("support profile sync", stopSupportProfileSync)
|
|
163
171
|
await safely("phone notifications sync", stopPhoneNotificationsSync)
|
|
172
|
+
await safely("phone activity tracking", stopPhoneActivityTracking)
|
|
164
173
|
await safely("speaker id sync", stopSpeakerIdSync)
|
|
165
174
|
await safely("captions tester report service", stopCaptionsTesterReportService)
|
|
166
|
-
await safely("
|
|
175
|
+
await safely("js crashloop report service", stopJSCrashloopReportService)
|
|
167
176
|
await safely("miniapp engine", stopMiniappEngine)
|
|
168
177
|
await safely("local miniapp runtime", () => localMiniappRuntime.cleanup())
|
|
169
178
|
await safely("display processor", () => displayProcessor.detachFromRuntime())
|
package/src/facades/dev.ts
CHANGED
|
@@ -20,6 +20,8 @@ import {getConfigValues} from "../runtime/bootstrap"
|
|
|
20
20
|
import {decideDevLaunchRoute} from "../utils/devMiniappLaunch"
|
|
21
21
|
import {deriveDevPackageId, registerDevApp, DEV_APP_PACKAGE_NAME, type DevAppRecord} from "../services/AppRegistry"
|
|
22
22
|
import {useAppStatusStore} from "../stores/apps"
|
|
23
|
+
import {sendGesture} from "../services/GlassesTouchInput"
|
|
24
|
+
import dashboardOpenTrace, {type DashboardOpenReport} from "../services/debug/DashboardOpenTrace"
|
|
23
25
|
|
|
24
26
|
type CloudUrlOverrides = {core?: string; runtime?: string}
|
|
25
27
|
|
|
@@ -90,6 +92,8 @@ function projectRuntimeStatus() {
|
|
|
90
92
|
export type DevRuntimeStatusSnapshot = ReturnType<typeof projectRuntimeStatus>
|
|
91
93
|
|
|
92
94
|
export const dev = {
|
|
95
|
+
/** Inject a glasses gesture through the normal dashboard/miniapp input policy. */
|
|
96
|
+
sendGesture,
|
|
93
97
|
/** The cloud-v2 core/runtime URL overrides. */
|
|
94
98
|
cloudUrls: (): {core?: string; runtime?: string} => {
|
|
95
99
|
const s = useSettingsStore.getState()
|
|
@@ -210,4 +214,10 @@ export const dev = {
|
|
|
210
214
|
unsubscribers.forEach((unsubscribe) => unsubscribe())
|
|
211
215
|
}
|
|
212
216
|
},
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Each finished dashboard open while the debug_dashboard_open_timing setting
|
|
220
|
+
* is on: a ready-made title/body plus the stage timings. Returns an unsubscribe.
|
|
221
|
+
*/
|
|
222
|
+
onDashboardOpenTrace: (cb: (report: DashboardOpenReport) => void): (() => void) => dashboardOpenTrace.onReport(cb),
|
|
213
223
|
}
|
package/src/facades/display.ts
CHANGED
|
@@ -5,20 +5,33 @@
|
|
|
5
5
|
* the engine DisplayProcessor / layout system, not these).
|
|
6
6
|
*/
|
|
7
7
|
import BluetoothSdk from "@glassly/bluetooth-sdk"
|
|
8
|
-
import
|
|
8
|
+
import {sendGesture} from "../services/GlassesTouchInput"
|
|
9
|
+
import localMiniappRuntime from "../services/LocalMiniappRuntime"
|
|
10
|
+
import {useDisplayStore} from "../stores/display"
|
|
9
11
|
import {displayMirror} from "./displayMirror"
|
|
10
12
|
|
|
11
13
|
export const display = {
|
|
12
14
|
/** Mirrored-view read-model (current/onMirror). */
|
|
13
15
|
mirror: displayMirror,
|
|
14
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Dashboard controls for the simulator and dev tools. The dashboard is a
|
|
18
|
+
* miniapp's (ADR-0006): these replay the wearer's own inputs, so they do
|
|
19
|
+
* whatever the running apps make of them.
|
|
20
|
+
*/
|
|
15
21
|
dashboard: {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
/** An overlay app holds the slot. */
|
|
23
|
+
isOpen: (): boolean => useDisplayStore.getState().overlayOwner !== null,
|
|
24
|
+
/** As if the head was raised/lowered (the dashboard app applies contextual_dashboard). */
|
|
25
|
+
setHeadUp: (up: boolean): void =>
|
|
26
|
+
localMiniappRuntime.forwardEvent("head_up", {position: up ? "up" : "down", timestamp: Date.now()}),
|
|
27
|
+
/** A double tap on the empty screen: the dashboard app opens (simulator button). */
|
|
28
|
+
open: (): void => {
|
|
29
|
+
if (!display.dashboard.isOpen()) sendGesture("double_tap")
|
|
30
|
+
},
|
|
31
|
+
/** A double tap on the showing page: it closes. */
|
|
32
|
+
close: (): void => {
|
|
33
|
+
if (display.dashboard.isOpen()) sendGesture("double_tap")
|
|
34
|
+
},
|
|
22
35
|
},
|
|
23
36
|
/** Write raw text to the glasses display at (x, y) with a font size. */
|
|
24
37
|
text: (...args: Parameters<typeof BluetoothSdk.displayText>) => BluetoothSdk.displayText(...args),
|
|
@@ -7,10 +7,20 @@
|
|
|
7
7
|
* The raw store is also exposed as `engine.displayStore` (the Glassly-app
|
|
8
8
|
* escape hatch).
|
|
9
9
|
*/
|
|
10
|
+
import displayProcessor from "../services/DisplayProcessor"
|
|
11
|
+
import {getEffectiveCapabilities} from "../services/effectiveCapabilities"
|
|
10
12
|
import {useDisplayStore} from "../stores/display"
|
|
13
|
+
import {useGlassesStore} from "../stores/glasses"
|
|
14
|
+
import {SETTINGS, useSettingsStore} from "../stores/settings"
|
|
15
|
+
import {DeviceTypes} from "../types"
|
|
11
16
|
|
|
12
17
|
export type DisplayMirrorEvent = Record<string, unknown> & {view?: string; layout?: any}
|
|
13
18
|
|
|
19
|
+
export interface DisplayMirrorCanvas {
|
|
20
|
+
width: number
|
|
21
|
+
height: number
|
|
22
|
+
}
|
|
23
|
+
|
|
14
24
|
export const displayMirror = {
|
|
15
25
|
/** The display event currently on the glasses (snapshot). */
|
|
16
26
|
current(): DisplayMirrorEvent {
|
|
@@ -22,4 +32,23 @@ export const displayMirror = {
|
|
|
22
32
|
onMirror(cb: (event: DisplayMirrorEvent) => void): () => void {
|
|
23
33
|
return useDisplayStore.subscribe((s) => s.currentEvent, cb)
|
|
24
34
|
},
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Drawable canvas of the selected glasses, in device px — the space scene
|
|
38
|
+
* frames and positioned layouts are laid out in (same source SceneRenderer
|
|
39
|
+
* sends CONNECT_ACK from). Falls back to the text profile's line width.
|
|
40
|
+
* `previewModel` previews a model that is not selected yet (pairing prep).
|
|
41
|
+
*/
|
|
42
|
+
canvas(previewModel?: string): DisplayMirrorCanvas {
|
|
43
|
+
const model =
|
|
44
|
+
previewModel ??
|
|
45
|
+
(useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key) as string | undefined) ??
|
|
46
|
+
(useGlassesStore.getState().deviceModel as string | undefined)
|
|
47
|
+
const display = getEffectiveCapabilities((model ?? DeviceTypes.NONE) as DeviceTypes)?.display
|
|
48
|
+
const profile = displayProcessor.getProfile()
|
|
49
|
+
return {
|
|
50
|
+
width: display?.width ?? display?.resolution?.width ?? profile.displayWidthPx,
|
|
51
|
+
height: display?.height ?? display?.resolution?.height ?? profile.displayHeightPx ?? profile.displayWidthPx / 2,
|
|
52
|
+
}
|
|
53
|
+
},
|
|
25
54
|
}
|
package/src/facades/glasses.ts
CHANGED
|
@@ -11,7 +11,14 @@
|
|
|
11
11
|
// surface, not the public entry. Relative path (the alias doesn't resolve in engine's
|
|
12
12
|
// standalone build); jest moduleNameMapper + tsconfig both resolve it.
|
|
13
13
|
import BluetoothSdk from "@glassly/bluetooth-sdk/internal"
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
ButtonPressEvent,
|
|
16
|
+
ConnectOptions,
|
|
17
|
+
Device,
|
|
18
|
+
KeyboardAdvertEvent,
|
|
19
|
+
KeyboardPairingEvent,
|
|
20
|
+
TouchEvent,
|
|
21
|
+
} from "@glassly/bluetooth-sdk"
|
|
15
22
|
import {useGlassesStore} from "../stores/glasses"
|
|
16
23
|
import {useSettingsStore, SETTINGS} from "../stores/settings"
|
|
17
24
|
import {hasDefaultDevice} from "../services/DeviceStoreHydration"
|
|
@@ -50,6 +57,20 @@ function projectControllerStatus() {
|
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
59
|
|
|
60
|
+
function projectKeyboardStatus() {
|
|
61
|
+
const s = useGlassesStore.getState()
|
|
62
|
+
return {
|
|
63
|
+
/** Connected glasses run a firmware that can host a keyboard (G2 Glassly CFW 39+). */
|
|
64
|
+
available: s.keyboardBridge === true,
|
|
65
|
+
connected: s.keyboardConnected === true,
|
|
66
|
+
name: s.keyboardName ?? "",
|
|
67
|
+
/** A keyboard is remembered and reconnects automatically. */
|
|
68
|
+
saved: s.keyboardSaved === true,
|
|
69
|
+
state: s.keyboardState ?? "idle",
|
|
70
|
+
error: s.keyboardError ?? "",
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
53
74
|
function projectInfo() {
|
|
54
75
|
const s = useGlassesStore.getState()
|
|
55
76
|
return {
|
|
@@ -77,6 +98,7 @@ function projectInfo() {
|
|
|
77
98
|
|
|
78
99
|
export type GlassesStatusSnapshot = ReturnType<typeof projectStatus>
|
|
79
100
|
export type ControllerStatusSnapshot = ReturnType<typeof projectControllerStatus>
|
|
101
|
+
export type KeyboardStatusSnapshot = ReturnType<typeof projectKeyboardStatus>
|
|
80
102
|
export type GlassesInfoSnapshot = ReturnType<typeof projectInfo>
|
|
81
103
|
|
|
82
104
|
export const glasses = {
|
|
@@ -189,6 +211,44 @@ export const glasses = {
|
|
|
189
211
|
return () => sub.remove()
|
|
190
212
|
},
|
|
191
213
|
|
|
214
|
+
// --- BLE keyboard bridged through G2 Glassly CFW (revision 39+) ---
|
|
215
|
+
keyboard: {
|
|
216
|
+
/** Five-second scan; distinct advertisers, HID ones flagged. Also streams via onAdvert. */
|
|
217
|
+
scan: (): Promise<KeyboardAdvertEvent[]> => BluetoothSdk.g2KeyboardScan(),
|
|
218
|
+
/** Connect, pair and subscribe; the keyboard is remembered and auto-reconnected. */
|
|
219
|
+
connect: async (device: {address: string; addressType: number; name: string}): Promise<void> => {
|
|
220
|
+
await BluetoothSdk.g2KeyboardConnect(device.address, device.addressType, device.name)
|
|
221
|
+
useSettingsStore.getState().setSetting(SETTINGS.keyboard_name.key, device.name)
|
|
222
|
+
},
|
|
223
|
+
reconnect: (): Promise<void> => BluetoothSdk.g2KeyboardReconnect(),
|
|
224
|
+
disconnect: (): Promise<void> => BluetoothSdk.g2KeyboardDisconnect(),
|
|
225
|
+
forget: async (): Promise<void> => {
|
|
226
|
+
await BluetoothSdk.g2KeyboardForget()
|
|
227
|
+
useSettingsStore.getState().setSetting(SETTINGS.keyboard_name.key, "")
|
|
228
|
+
},
|
|
229
|
+
passkey: (pin: number): Promise<void> => BluetoothSdk.g2KeyboardPasskey(pin),
|
|
230
|
+
compare: (accept: boolean): Promise<void> => BluetoothSdk.g2KeyboardCompare(accept),
|
|
231
|
+
status: (): KeyboardStatusSnapshot => projectKeyboardStatus(),
|
|
232
|
+
onStatus: (cb: (status: KeyboardStatusSnapshot) => void): (() => void) => {
|
|
233
|
+
let last = JSON.stringify(projectKeyboardStatus())
|
|
234
|
+
return useGlassesStore.subscribe(() => {
|
|
235
|
+
const snap = projectKeyboardStatus()
|
|
236
|
+
const key = JSON.stringify(snap)
|
|
237
|
+
if (key === last) return
|
|
238
|
+
last = key
|
|
239
|
+
cb(snap)
|
|
240
|
+
})
|
|
241
|
+
},
|
|
242
|
+
onAdvert: (cb: (advert: KeyboardAdvertEvent) => void): (() => void) => {
|
|
243
|
+
const sub = BluetoothSdk.addListener("keyboard_advert", cb)
|
|
244
|
+
return () => sub.remove()
|
|
245
|
+
},
|
|
246
|
+
onPairing: (cb: (prompt: KeyboardPairingEvent) => void): (() => void) => {
|
|
247
|
+
const sub = BluetoothSdk.addListener("keyboard_pairing", cb)
|
|
248
|
+
return () => sub.remove()
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
|
|
192
252
|
// --- ring controller (optional input device) ---
|
|
193
253
|
controller: {
|
|
194
254
|
connectDefault: (): Promise<void> => BluetoothSdk.connectDefaultController(),
|
package/src/facades/memory.ts
CHANGED
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
import type {MemoryEntry, MemorySession} from "@glassly/miniapp"
|
|
8
8
|
|
|
9
9
|
import type {MemoryStats} from "../services/MemoryStore"
|
|
10
|
-
import {
|
|
11
|
-
import {isMemoryRetentionExtended, memoryStore, setMemoryRetentionExtended} from "../services/memoryStoreInstance"
|
|
10
|
+
import {memoryStore} from "../services/memoryStoreInstance"
|
|
12
11
|
|
|
13
12
|
export const memory = {
|
|
14
13
|
/** All note entries, newest first. */
|
|
@@ -33,14 +32,4 @@ export const memory = {
|
|
|
33
32
|
clearAll: (): Promise<void> => memoryStore.clear(),
|
|
34
33
|
/** Subscribe to store mutations (from miniapps or Settings). */
|
|
35
34
|
onChanged: (listener: () => void): (() => void) => memoryStore.onChanged(listener),
|
|
36
|
-
/** Whether the extended (Plus/Pro) retention window is active. */
|
|
37
|
-
retentionExtended: (): boolean => isMemoryRetentionExtended(),
|
|
38
|
-
/** Retention window in days for the given (or current) tier, for UI copy. */
|
|
39
|
-
retentionDays: (extended?: boolean): number =>
|
|
40
|
-
Math.round(
|
|
41
|
-
((extended ?? isMemoryRetentionExtended()) ? EXTENDED_RETENTION : STANDARD_RETENTION).maxAgeMs /
|
|
42
|
-
(24 * 60 * 60 * 1000),
|
|
43
|
-
),
|
|
44
|
-
/** Flip retention on subscription change. Host app (RevenueCat sync) only. */
|
|
45
|
-
setRetentionExtended: (extended: boolean): void => setMemoryRetentionExtended(extended),
|
|
46
35
|
}
|
package/src/facades/miniapps.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* The miniapp WebView is a HOST component (engine ships the bridge, not the view) —
|
|
7
7
|
* the bridge primitives (`buildMiniappGlobalsScript`, `buildUiShim`, the
|
|
8
|
-
*
|
|
8
|
+
* JSRuntime router) are exported from `@glassly/engine` directly; the host mounts a
|
|
9
9
|
* `<WebView>` wired to them. This facade is the lifecycle half.
|
|
10
10
|
*/
|
|
11
11
|
import {useAppStatusStore} from "../stores/apps"
|
|
@@ -59,4 +59,7 @@ export const miniapps = {
|
|
|
59
59
|
/** Hide/show a miniapp on the home surfaces. */
|
|
60
60
|
setHiddenStatus: (...args: Parameters<AppsState["setHiddenStatus"]>) =>
|
|
61
61
|
useAppStatusStore.getState().setHiddenStatus(...args),
|
|
62
|
+
/** Mark a miniapp persistent (starts at launch, stops only from the switcher pill), persisted for the next boot. */
|
|
63
|
+
setPersistent: (...args: Parameters<AppsState["setPersistent"]>) =>
|
|
64
|
+
useAppStatusStore.getState().setPersistent(...args),
|
|
62
65
|
}
|
package/src/facades/pairing.ts
CHANGED
|
@@ -31,6 +31,8 @@ import {pushAllBluetoothSettings} from "../services/GlassesSettingsSync"
|
|
|
31
31
|
import {ControllerTypes} from "../types"
|
|
32
32
|
import {submitAutomaticReport} from "./reports"
|
|
33
33
|
|
|
34
|
+
import {BgTimer} from "../utils/timers"
|
|
35
|
+
|
|
34
36
|
export type {IdentitySnapshot} from "../services/PairingIdentity"
|
|
35
37
|
|
|
36
38
|
export interface PairingReadyWaitOptions {
|
|
@@ -110,13 +112,13 @@ async function waitForTargetReady(options: PairingReadyWaitOptions, timeoutMs: n
|
|
|
110
112
|
}
|
|
111
113
|
|
|
112
114
|
let settled = false
|
|
113
|
-
let timeout:
|
|
115
|
+
let timeout: number | null = null
|
|
114
116
|
let unsubscribe: (() => void) | null = null
|
|
115
117
|
let onAbort: (() => void) | null = null
|
|
116
118
|
const finish = (ready: boolean) => {
|
|
117
119
|
if (settled) return
|
|
118
120
|
settled = true
|
|
119
|
-
if (timeout) clearTimeout(timeout)
|
|
121
|
+
if (timeout) BgTimer.clearTimeout(timeout)
|
|
120
122
|
if (unsubscribe) unsubscribe()
|
|
121
123
|
if (onAbort && options.signal) options.signal.removeEventListener("abort", onAbort)
|
|
122
124
|
resolve(ready)
|
|
@@ -129,7 +131,7 @@ async function waitForTargetReady(options: PairingReadyWaitOptions, timeoutMs: n
|
|
|
129
131
|
onAbort = () => finish(false)
|
|
130
132
|
options.signal.addEventListener("abort", onAbort)
|
|
131
133
|
}
|
|
132
|
-
timeout = setTimeout(() => finish(projectTargetReady(options)), timeoutMs)
|
|
134
|
+
timeout = BgTimer.setTimeout(() => finish(projectTargetReady(options)), timeoutMs)
|
|
133
135
|
})
|
|
134
136
|
}
|
|
135
137
|
|
|
@@ -218,14 +220,14 @@ async function waitForBluetoothClassic(
|
|
|
218
220
|
}
|
|
219
221
|
|
|
220
222
|
let settled = false
|
|
221
|
-
let timeout:
|
|
223
|
+
let timeout: number | null = null
|
|
222
224
|
let unsubscribe: (() => void) | null = null
|
|
223
225
|
let onAbort: (() => void) | null = null
|
|
224
226
|
|
|
225
227
|
const finish = (value: boolean) => {
|
|
226
228
|
if (settled) return
|
|
227
229
|
settled = true
|
|
228
|
-
if (timeout) clearTimeout(timeout)
|
|
230
|
+
if (timeout) BgTimer.clearTimeout(timeout)
|
|
229
231
|
if (unsubscribe) unsubscribe()
|
|
230
232
|
if (onAbort && options.signal) options.signal.removeEventListener("abort", onAbort)
|
|
231
233
|
resolve(value)
|
|
@@ -243,7 +245,7 @@ async function waitForBluetoothClassic(
|
|
|
243
245
|
},
|
|
244
246
|
)
|
|
245
247
|
|
|
246
|
-
timeout = setTimeout(() => {
|
|
248
|
+
timeout = BgTimer.setTimeout(() => {
|
|
247
249
|
finish(useGlassesStore.getState().bluetoothClassicConnected)
|
|
248
250
|
}, timeoutMs)
|
|
249
251
|
})
|