@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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { displayMirror } from "../facades/displayMirror";
|
|
2
|
+
import { useDisplayStore } from "../stores/display";
|
|
3
|
+
import { useGlassesStore } from "../stores/glasses";
|
|
4
|
+
import { SETTINGS, useSettingsStore } from "../stores/settings";
|
|
5
|
+
import { DeviceTypes } from "../types";
|
|
6
|
+
import { BgTimer } from "../utils/timers";
|
|
7
|
+
import displayProcessor from "./DisplayProcessor";
|
|
8
|
+
import { getEffectiveCapabilities } from "./effectiveCapabilities";
|
|
9
|
+
import { isGlassesConnected } from "./GlassesReadiness";
|
|
10
|
+
import { buildMirrorSnapshot } from "./mirrorSnapshot";
|
|
11
|
+
/** One host-wide preview producer, observed only while miniapps subscribe. */
|
|
12
|
+
class MirrorService {
|
|
13
|
+
revision = 0;
|
|
14
|
+
lastKey = "";
|
|
15
|
+
lastEvent;
|
|
16
|
+
snapshot = null;
|
|
17
|
+
model = null;
|
|
18
|
+
initialized = false;
|
|
19
|
+
listeners = new Set();
|
|
20
|
+
stops = [];
|
|
21
|
+
lastEmittedRevision = 0;
|
|
22
|
+
pendingEvent;
|
|
23
|
+
pendingFrames = 0;
|
|
24
|
+
timer = null;
|
|
25
|
+
selectedModel() {
|
|
26
|
+
return (useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key) ||
|
|
27
|
+
useGlassesStore.getState().deviceModel ||
|
|
28
|
+
null);
|
|
29
|
+
}
|
|
30
|
+
initialize() {
|
|
31
|
+
if (this.initialized)
|
|
32
|
+
return;
|
|
33
|
+
this.initialized = true;
|
|
34
|
+
this.model = this.selectedModel();
|
|
35
|
+
// Keep stale content from a previous pair out of queries, even when no
|
|
36
|
+
// preview is open. No frame serialization runs in these observers.
|
|
37
|
+
const invalidateModel = () => {
|
|
38
|
+
const model = this.selectedModel();
|
|
39
|
+
if (model === this.model)
|
|
40
|
+
return;
|
|
41
|
+
this.model = model;
|
|
42
|
+
this.invalidate("device-changed");
|
|
43
|
+
};
|
|
44
|
+
useGlassesStore.subscribe(invalidateModel);
|
|
45
|
+
useSettingsStore.subscribe(invalidateModel);
|
|
46
|
+
}
|
|
47
|
+
invalidate(reason) {
|
|
48
|
+
useDisplayStore.getState().setDisplayEvent({ layout: { layoutType: "unavailable", reason } });
|
|
49
|
+
}
|
|
50
|
+
current() {
|
|
51
|
+
this.initialize();
|
|
52
|
+
const gs = useGlassesStore.getState();
|
|
53
|
+
const model = this.selectedModel();
|
|
54
|
+
const event = useDisplayStore.getState().currentEvent;
|
|
55
|
+
const connected = isGlassesConnected(gs.connection);
|
|
56
|
+
const canvas = getEffectiveCapabilities((model ?? DeviceTypes.NONE))?.display
|
|
57
|
+
? displayMirror.canvas()
|
|
58
|
+
: null;
|
|
59
|
+
const now = Date.now();
|
|
60
|
+
const key = JSON.stringify([model, connected, canvas, gs.batteryLevel, Math.floor(now / 60000)]);
|
|
61
|
+
if (!this.snapshot || event !== this.lastEvent || key !== this.lastKey) {
|
|
62
|
+
this.lastEvent = event;
|
|
63
|
+
this.lastKey = key;
|
|
64
|
+
this.snapshot = buildMirrorSnapshot({
|
|
65
|
+
event,
|
|
66
|
+
canvas,
|
|
67
|
+
connected,
|
|
68
|
+
model,
|
|
69
|
+
battery: gs.batteryLevel,
|
|
70
|
+
measureChar: (char) => displayProcessor.measureChar(char),
|
|
71
|
+
now,
|
|
72
|
+
}, ++this.revision);
|
|
73
|
+
}
|
|
74
|
+
return this.snapshot;
|
|
75
|
+
}
|
|
76
|
+
subscribe(cb) {
|
|
77
|
+
this.initialize();
|
|
78
|
+
this.listeners.add(cb);
|
|
79
|
+
if (this.listeners.size === 1) {
|
|
80
|
+
// Coalesce to the newest state at most every 33ms. The SDK renderer snaps
|
|
81
|
+
// across skipped revisions rather than replaying obsolete transitions.
|
|
82
|
+
const schedule = () => {
|
|
83
|
+
const event = useDisplayStore.getState().currentEvent;
|
|
84
|
+
if (event !== this.pendingEvent) {
|
|
85
|
+
this.pendingEvent = event;
|
|
86
|
+
this.pendingFrames++;
|
|
87
|
+
}
|
|
88
|
+
if (this.timer)
|
|
89
|
+
return;
|
|
90
|
+
this.timer = BgTimer.setTimeout(() => {
|
|
91
|
+
this.timer = null;
|
|
92
|
+
let next = this.current();
|
|
93
|
+
if (this.pendingFrames > 1 && next.content.kind === "scene") {
|
|
94
|
+
next = {
|
|
95
|
+
...next,
|
|
96
|
+
content: {
|
|
97
|
+
...next.content,
|
|
98
|
+
elements: next.content.elements.map((element) => ({ ...element, change: "created" })),
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
this.pendingFrames = 0;
|
|
103
|
+
if (next.revision !== this.lastEmittedRevision) {
|
|
104
|
+
this.lastEmittedRevision = next.revision;
|
|
105
|
+
for (const listener of this.listeners)
|
|
106
|
+
listener(next);
|
|
107
|
+
}
|
|
108
|
+
}, 33);
|
|
109
|
+
};
|
|
110
|
+
this.pendingEvent = useDisplayStore.getState().currentEvent;
|
|
111
|
+
this.pendingFrames = 0;
|
|
112
|
+
this.stops = [
|
|
113
|
+
useDisplayStore.subscribe(schedule),
|
|
114
|
+
useGlassesStore.subscribe(schedule),
|
|
115
|
+
useSettingsStore.subscribe(schedule),
|
|
116
|
+
];
|
|
117
|
+
const clock = BgTimer.setInterval(schedule, 1000);
|
|
118
|
+
this.stops.push(() => BgTimer.clearInterval(clock));
|
|
119
|
+
}
|
|
120
|
+
return () => {
|
|
121
|
+
this.listeners.delete(cb);
|
|
122
|
+
if (this.listeners.size)
|
|
123
|
+
return;
|
|
124
|
+
this.stops.splice(0).forEach((stop) => stop());
|
|
125
|
+
if (this.timer)
|
|
126
|
+
BgTimer.clearTimeout(this.timer);
|
|
127
|
+
this.timer = null;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export const mirrorService = new MirrorService();
|
|
132
|
+
//# sourceMappingURL=MirrorService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MirrorService.js","sourceRoot":"","sources":["../../src/services/MirrorService.ts"],"names":[],"mappings":"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","sourcesContent":["import type {MirrorSnapshot} from \"@glassly/miniapp\"\n\nimport {displayMirror} from \"../facades/displayMirror\"\nimport {useDisplayStore} from \"../stores/display\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {DeviceTypes} from \"../types\"\nimport {BgTimer} from \"../utils/timers\"\nimport displayProcessor from \"./DisplayProcessor\"\nimport {getEffectiveCapabilities} from \"./effectiveCapabilities\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\nimport {buildMirrorSnapshot} from \"./mirrorSnapshot\"\n\n/** One host-wide preview producer, observed only while miniapps subscribe. */\nclass MirrorService {\n private revision = 0\n private lastKey = \"\"\n private lastEvent: unknown\n private snapshot: MirrorSnapshot | null = null\n private model: string | null = null\n private initialized = false\n private listeners = new Set<(snapshot: MirrorSnapshot) => void>()\n private stops: Array<() => void> = []\n private lastEmittedRevision = 0\n private pendingEvent: unknown\n private pendingFrames = 0\n private timer: ReturnType<typeof BgTimer.setTimeout> | null = null\n\n private selectedModel(): string | null {\n return (\n (useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key) as string) ||\n useGlassesStore.getState().deviceModel ||\n null\n )\n }\n\n initialize(): void {\n if (this.initialized) return\n this.initialized = true\n this.model = this.selectedModel()\n // Keep stale content from a previous pair out of queries, even when no\n // preview is open. No frame serialization runs in these observers.\n const invalidateModel = () => {\n const model = this.selectedModel()\n if (model === this.model) return\n this.model = model\n this.invalidate(\"device-changed\")\n }\n useGlassesStore.subscribe(invalidateModel)\n useSettingsStore.subscribe(invalidateModel)\n }\n\n invalidate(reason: string): void {\n useDisplayStore.getState().setDisplayEvent({layout: {layoutType: \"unavailable\", reason}})\n }\n\n current(): MirrorSnapshot {\n this.initialize()\n const gs = useGlassesStore.getState()\n const model = this.selectedModel()\n const event = useDisplayStore.getState().currentEvent\n const connected = isGlassesConnected(gs.connection)\n const canvas = getEffectiveCapabilities((model ?? DeviceTypes.NONE) as DeviceTypes)?.display\n ? displayMirror.canvas()\n : null\n const now = Date.now()\n const key = JSON.stringify([model, connected, canvas, gs.batteryLevel, Math.floor(now / 60000)])\n if (!this.snapshot || event !== this.lastEvent || key !== this.lastKey) {\n this.lastEvent = event\n this.lastKey = key\n this.snapshot = buildMirrorSnapshot(\n {\n event,\n canvas,\n connected,\n model,\n battery: gs.batteryLevel,\n measureChar: (char) => displayProcessor.measureChar(char),\n now,\n },\n ++this.revision,\n )\n }\n return this.snapshot\n }\n\n subscribe(cb: (snapshot: MirrorSnapshot) => void): () => void {\n this.initialize()\n this.listeners.add(cb)\n if (this.listeners.size === 1) {\n // Coalesce to the newest state at most every 33ms. The SDK renderer snaps\n // across skipped revisions rather than replaying obsolete transitions.\n const schedule = () => {\n const event = useDisplayStore.getState().currentEvent\n if (event !== this.pendingEvent) {\n this.pendingEvent = event\n this.pendingFrames++\n }\n if (this.timer) return\n this.timer = BgTimer.setTimeout(() => {\n this.timer = null\n let next = this.current()\n if (this.pendingFrames > 1 && next.content.kind === \"scene\") {\n next = {\n ...next,\n content: {\n ...next.content,\n elements: next.content.elements.map((element) => ({...element, change: \"created\" as const})),\n },\n }\n }\n this.pendingFrames = 0\n if (next.revision !== this.lastEmittedRevision) {\n this.lastEmittedRevision = next.revision\n for (const listener of this.listeners) listener(next)\n }\n }, 33)\n }\n this.pendingEvent = useDisplayStore.getState().currentEvent\n this.pendingFrames = 0\n this.stops = [\n useDisplayStore.subscribe(schedule),\n useGlassesStore.subscribe(schedule),\n useSettingsStore.subscribe(schedule),\n ]\n const clock = BgTimer.setInterval(schedule, 1000)\n this.stops.push(() => BgTimer.clearInterval(clock))\n }\n return () => {\n this.listeners.delete(cb)\n if (this.listeners.size) return\n this.stops.splice(0).forEach((stop) => stop())\n if (this.timer) BgTimer.clearTimeout(this.timer)\n this.timer = null\n }\n }\n}\n\nexport const mirrorService = new MirrorService()\n"]}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* firmware-rendered nav UI (`hasNativeNavigation`; G2 service 0x08 today).
|
|
4
4
|
* NavigationHandlers drives enter/exit at trip boundaries; miniapp NATIVE_NAV
|
|
5
5
|
* payloads (card fields, map bitmaps) are forwarded to the bluetooth-sdk.
|
|
6
|
-
* While active,
|
|
7
|
-
* session.
|
|
6
|
+
* While active, stock firmware streams its magnetometer heading; the device
|
|
7
|
+
* event router forwards it to session.compass like any glasses compass sample.
|
|
8
8
|
*/
|
|
9
9
|
export interface NativeNavInfoPayload {
|
|
10
10
|
directionIcon: number;
|
|
@@ -18,7 +18,6 @@ export interface NativeNavInfoPayload {
|
|
|
18
18
|
declare class NativeNavigationService {
|
|
19
19
|
private static instance;
|
|
20
20
|
private active;
|
|
21
|
-
private compassSub;
|
|
22
21
|
private modeSub;
|
|
23
22
|
/** Registered by NavigationHandlers; fires when the WEARER exits nav mode on the glasses. */
|
|
24
23
|
private onGlassesExitCb;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeNavigationService.d.ts","sourceRoot":"","sources":["../../src/services/NativeNavigationService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"NativeNavigationService.d.ts","sourceRoot":"","sources":["../../src/services/NativeNavigationService.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;CACd;AAED,cAAM,uBAAuB;IAC3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAuC;IAE9D,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,OAAO,CAAoC;IACnD,6FAA6F;IAC7F,OAAO,CAAC,eAAe,CAA4B;IAEnD,OAAO;IAEA,gBAAgB,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;WAIxC,WAAW,IAAI,uBAAuB;IAOpD,8DAA8D;IAC9D,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED;;;;OAIG;IACI,WAAW,IAAI,OAAO;IAa7B,iEAAiE;IAC1D,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAgB7C,gFAAgF;IACzE,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAaxC;;;;OAIG;IACI,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IA4CtE,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,QAAQ;CAKjB;AAED,QAAA,MAAM,uBAAuB,yBAAwC,CAAA;AACrE,eAAe,uBAAuB,CAAA"}
|
|
@@ -3,19 +3,20 @@
|
|
|
3
3
|
* firmware-rendered nav UI (`hasNativeNavigation`; G2 service 0x08 today).
|
|
4
4
|
* NavigationHandlers drives enter/exit at trip boundaries; miniapp NATIVE_NAV
|
|
5
5
|
* payloads (card fields, map bitmaps) are forwarded to the bluetooth-sdk.
|
|
6
|
-
* While active,
|
|
7
|
-
* session.
|
|
6
|
+
* While active, stock firmware streams its magnetometer heading; the device
|
|
7
|
+
* event router forwards it to session.compass like any glasses compass sample.
|
|
8
8
|
*/
|
|
9
|
+
import { useDisplayStore } from "../stores/display";
|
|
9
10
|
import BluetoothSdk from "@glassly/bluetooth-sdk/internal";
|
|
10
11
|
import { ISLAND_SETTINGS_KEYS } from "../runtime/config";
|
|
11
12
|
import { useSettingsStore } from "../stores/settings";
|
|
12
|
-
import { DeviceTypes
|
|
13
|
-
import
|
|
13
|
+
import { DeviceTypes } from "../types";
|
|
14
|
+
import { getEffectiveCapabilities } from "./effectiveCapabilities";
|
|
15
|
+
import glassesSensorService from "./GlassesSensorService";
|
|
14
16
|
const LOG_TAG = "NATIVE_NAV_SERVICE";
|
|
15
17
|
class NativeNavigationService {
|
|
16
18
|
static instance = null;
|
|
17
19
|
active = false;
|
|
18
|
-
compassSub = null;
|
|
19
20
|
modeSub = null;
|
|
20
21
|
/** Registered by NavigationHandlers; fires when the WEARER exits nav mode on the glasses. */
|
|
21
22
|
onGlassesExitCb = null;
|
|
@@ -40,7 +41,9 @@ class NativeNavigationService {
|
|
|
40
41
|
*/
|
|
41
42
|
isSupported() {
|
|
42
43
|
const defaultWearable = useSettingsStore.getState().getSetting(ISLAND_SETTINGS_KEYS.defaultWearable);
|
|
43
|
-
|
|
44
|
+
// Effective, not model: custom firmware drops hasNativeNavigation so the
|
|
45
|
+
// miniapp's scene HUD owns the display (see effectiveCapabilities).
|
|
46
|
+
const capabilities = getEffectiveCapabilities(defaultWearable || DeviceTypes.NONE);
|
|
44
47
|
return (capabilities.hasNativeNavigation === true &&
|
|
45
48
|
typeof BluetoothSdk.navigationModeStart === "function");
|
|
46
49
|
}
|
|
@@ -50,8 +53,14 @@ class NativeNavigationService {
|
|
|
50
53
|
return;
|
|
51
54
|
console.log(`${LOG_TAG}: entering native nav mode for ${packageName}`);
|
|
52
55
|
this.active = true;
|
|
56
|
+
useDisplayStore.getState().setDisplayEvent({ layout: { layoutType: "unavailable", reason: "firmware-navigation" } });
|
|
53
57
|
this.attachListeners();
|
|
54
|
-
void
|
|
58
|
+
void glassesSensorService
|
|
59
|
+
.setNavigationActive(true)
|
|
60
|
+
.then(() => {
|
|
61
|
+
return this.active ? BluetoothSdk.navigationModeStart() : undefined;
|
|
62
|
+
})
|
|
63
|
+
.catch((err) => {
|
|
55
64
|
console.error(`${LOG_TAG}: navigationModeStart failed:`, err);
|
|
56
65
|
});
|
|
57
66
|
}
|
|
@@ -61,7 +70,11 @@ class NativeNavigationService {
|
|
|
61
70
|
return;
|
|
62
71
|
console.log(`${LOG_TAG}: exiting native nav mode (arrived=${arrived})`);
|
|
63
72
|
this.teardown();
|
|
64
|
-
void Promise.resolve(BluetoothSdk.navigationModeStop(arrived))
|
|
73
|
+
void Promise.resolve(BluetoothSdk.navigationModeStop(arrived))
|
|
74
|
+
.then(() => {
|
|
75
|
+
return glassesSensorService.setNavigationActive(false);
|
|
76
|
+
})
|
|
77
|
+
.catch((err) => {
|
|
65
78
|
console.error(`${LOG_TAG}: navigationModeStop failed:`, err);
|
|
66
79
|
});
|
|
67
80
|
}
|
|
@@ -118,15 +131,6 @@ class NativeNavigationService {
|
|
|
118
131
|
}
|
|
119
132
|
}
|
|
120
133
|
attachListeners() {
|
|
121
|
-
// Glasses magnetometer → session.heading for the duration of the trip.
|
|
122
|
-
headingService.setExternalSourceActive(true);
|
|
123
|
-
this.compassSub?.remove();
|
|
124
|
-
this.compassSub = BluetoothSdk.addListener("compass_heading", (event) => {
|
|
125
|
-
const deg = Number(event.heading);
|
|
126
|
-
if (!Number.isFinite(deg))
|
|
127
|
-
return;
|
|
128
|
-
headingService.pushExternalHeading(((deg % 360) + 360) % 360);
|
|
129
|
-
});
|
|
130
134
|
// Glasses-side exit ends the whole trip: release the compass override and
|
|
131
135
|
// let NavigationHandlers stop navigation + notify the miniapp ("cancelled").
|
|
132
136
|
// Phone-initiated exits (trip already ending) just tear down.
|
|
@@ -135,18 +139,17 @@ class NativeNavigationService {
|
|
|
135
139
|
if (event.status === "exited" && this.active) {
|
|
136
140
|
console.log(`${LOG_TAG}: nav mode exited natively (source=${event.source ?? "phone"})`);
|
|
137
141
|
this.teardown();
|
|
138
|
-
if (event.source === "glasses")
|
|
142
|
+
if (event.source === "glasses") {
|
|
139
143
|
this.onGlassesExitCb?.();
|
|
144
|
+
void glassesSensorService.setNavigationActive(false);
|
|
145
|
+
}
|
|
140
146
|
}
|
|
141
147
|
});
|
|
142
148
|
}
|
|
143
149
|
teardown() {
|
|
144
150
|
this.active = false;
|
|
145
|
-
this.compassSub?.remove();
|
|
146
|
-
this.compassSub = null;
|
|
147
151
|
this.modeSub?.remove();
|
|
148
152
|
this.modeSub = null;
|
|
149
|
-
headingService.setExternalSourceActive(false);
|
|
150
153
|
}
|
|
151
154
|
}
|
|
152
155
|
const nativeNavigationService = NativeNavigationService.getInstance();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeNavigationService.js","sourceRoot":"","sources":["../../src/services/NativeNavigationService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * NativeNavigationService — trip-scoped bridge to glasses with a\n * firmware-rendered nav UI (`hasNativeNavigation`; G2 service 0x08 today).\n * NavigationHandlers drives enter/exit at trip boundaries; miniapp NATIVE_NAV\n * payloads (card fields, map bitmaps) are forwarded to the bluetooth-sdk.\n * While active, the glasses magnetometer feeds HeadingService so\n * session.heading serves the glasses compass instead of the phone's.\n */\n\nimport BluetoothSdk from \"@glassly/bluetooth-sdk/internal\"\n\nimport {ISLAND_SETTINGS_KEYS} from \"../runtime/config\"\nimport {useSettingsStore} from \"../stores/settings\"\nimport {DeviceTypes, getModelCapabilities} from \"../types\"\nimport headingService from \"./HeadingService\"\n\nconst LOG_TAG = \"NATIVE_NAV_SERVICE\"\n\nexport interface NativeNavInfoPayload {\n directionIcon: number\n distance: string\n roadName: string\n spendTime: string\n remainDistance: string\n etaTime: string\n speed: string\n}\n\nclass NativeNavigationService {\n private static instance: NativeNavigationService | null = null\n\n private active = false\n private compassSub: {remove: () => void} | null = null\n private modeSub: {remove: () => void} | null = null\n /** Registered by NavigationHandlers; fires when the WEARER exits nav mode on the glasses. */\n private onGlassesExitCb: (() => void) | null = null\n\n private constructor() {}\n\n public setOnGlassesExit(cb: (() => void) | null): void {\n this.onGlassesExitCb = cb\n }\n\n public static getInstance(): NativeNavigationService {\n if (!NativeNavigationService.instance) {\n NativeNavigationService.instance = new NativeNavigationService()\n }\n return NativeNavigationService.instance\n }\n\n /** True while the glasses' native nav UI owns the display. */\n public get isActive(): boolean {\n return this.active\n }\n\n /**\n * True when the paired glasses render their own nav UI AND this native\n * build exposes the nav-mode functions (both platforms since the G2.kt\n * port — the typeof guard keeps older builds safe).\n */\n public isSupported(): boolean {\n const defaultWearable = useSettingsStore.getState().getSetting(ISLAND_SETTINGS_KEYS.defaultWearable) as\n | DeviceTypes\n | undefined\n const capabilities = getModelCapabilities(defaultWearable || DeviceTypes.NONE)\n return (\n capabilities.hasNativeNavigation === true &&\n typeof (BluetoothSdk as {navigationModeStart?: unknown}).navigationModeStart === \"function\"\n )\n }\n\n /** A trip started (NavigationHandlers.handleStart succeeded). */\n public onTripStart(packageName: string): void {\n if (!this.isSupported() || this.active) return\n console.log(`${LOG_TAG}: entering native nav mode for ${packageName}`)\n this.active = true\n this.attachListeners()\n void Promise.resolve(BluetoothSdk.navigationModeStart()).catch((err) => {\n console.error(`${LOG_TAG}: navigationModeStart failed:`, err)\n })\n }\n\n /** The trip ended (arrived / stopped / errored). Safe to call when inactive. */\n public onTripEnd(arrived: boolean): void {\n if (!this.active) return\n console.log(`${LOG_TAG}: exiting native nav mode (arrived=${arrived})`)\n this.teardown()\n void Promise.resolve(BluetoothSdk.navigationModeStop(arrived)).catch((err) => {\n console.error(`${LOG_TAG}: navigationModeStop failed:`, err)\n })\n }\n\n /**\n * Forward a miniapp NATIVE_NAV payload to the glasses. Returns false when\n * native nav isn't active/supported (the SDK reports \"unsupported\" so the\n * miniapp can skip re-encoding bitmaps it doesn't need).\n */\n public handleMiniappRequest(payload: Record<string, unknown>): boolean {\n if (!this.active || !this.isSupported()) return false\n const action = payload.action\n try {\n switch (action) {\n case \"info\": {\n const info = (payload.info ?? {}) as Partial<NativeNavInfoPayload>\n void BluetoothSdk.navigationUpdateInfo({\n directionIcon: Number(info.directionIcon) || 0,\n distance: String(info.distance ?? \"\"),\n roadName: String(info.roadName ?? \"\"),\n spendTime: String(info.spendTime ?? \"\"),\n remainDistance: String(info.remainDistance ?? \"\"),\n etaTime: String(info.etaTime ?? \"\"),\n speed: String(info.speed ?? \"\"),\n })\n return true\n }\n case \"mini_map\": {\n const map = (payload.map ?? {}) as {data?: unknown; rotationDeg?: unknown; border?: unknown}\n if (typeof map.data !== \"string\" || map.data.length === 0) return false\n void BluetoothSdk.navigationMiniMap({\n data: map.data,\n rotationDeg: Number(map.rotationDeg) || 0,\n border: map.border !== false,\n })\n return true\n }\n case \"overview_map\": {\n const map = (payload.map ?? {}) as {data?: unknown}\n if (typeof map.data !== \"string\" || map.data.length === 0) return false\n void BluetoothSdk.navigationOverviewMap({data: map.data})\n return true\n }\n default:\n console.warn(`${LOG_TAG}: unknown native nav action:`, action)\n return false\n }\n } catch (err) {\n console.error(`${LOG_TAG}: native nav forward failed:`, err)\n return false\n }\n }\n\n private attachListeners(): void {\n // Glasses magnetometer → session.heading for the duration of the trip.\n headingService.setExternalSourceActive(true)\n this.compassSub?.remove()\n this.compassSub = BluetoothSdk.addListener(\"compass_heading\", (event) => {\n const deg = Number(event.heading)\n if (!Number.isFinite(deg)) return\n headingService.pushExternalHeading(((deg % 360) + 360) % 360)\n })\n\n // Glasses-side exit ends the whole trip: release the compass override and\n // let NavigationHandlers stop navigation + notify the miniapp (\"cancelled\").\n // Phone-initiated exits (trip already ending) just tear down.\n this.modeSub?.remove()\n this.modeSub = BluetoothSdk.addListener(\"navigation_mode_change\", (event) => {\n if (event.status === \"exited\" && this.active) {\n console.log(`${LOG_TAG}: nav mode exited natively (source=${event.source ?? \"phone\"})`)\n this.teardown()\n if (event.source === \"glasses\") this.onGlassesExitCb?.()\n }\n })\n }\n\n private teardown(): void {\n this.active = false\n this.compassSub?.remove()\n this.compassSub = null\n this.modeSub?.remove()\n this.modeSub = null\n headingService.setExternalSourceActive(false)\n }\n}\n\nconst nativeNavigationService = NativeNavigationService.getInstance()\nexport default nativeNavigationService\n"]}
|
|
1
|
+
{"version":3,"file":"NativeNavigationService.js","sourceRoot":"","sources":["../../src/services/NativeNavigationService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * NativeNavigationService — trip-scoped bridge to glasses with a\n * firmware-rendered nav UI (`hasNativeNavigation`; G2 service 0x08 today).\n * NavigationHandlers drives enter/exit at trip boundaries; miniapp NATIVE_NAV\n * payloads (card fields, map bitmaps) are forwarded to the bluetooth-sdk.\n * While active, stock firmware streams its magnetometer heading; the device\n * event router forwards it to session.compass like any glasses compass sample.\n */\n\nimport {useDisplayStore} from \"../stores/display\"\nimport BluetoothSdk from \"@glassly/bluetooth-sdk/internal\"\n\nimport {ISLAND_SETTINGS_KEYS} from \"../runtime/config\"\nimport {useSettingsStore} from \"../stores/settings\"\nimport {DeviceTypes} from \"../types\"\nimport {getEffectiveCapabilities} from \"./effectiveCapabilities\"\nimport glassesSensorService from \"./GlassesSensorService\"\n\nconst LOG_TAG = \"NATIVE_NAV_SERVICE\"\n\nexport interface NativeNavInfoPayload {\n directionIcon: number\n distance: string\n roadName: string\n spendTime: string\n remainDistance: string\n etaTime: string\n speed: string\n}\n\nclass NativeNavigationService {\n private static instance: NativeNavigationService | null = null\n\n private active = false\n private modeSub: {remove: () => void} | null = null\n /** Registered by NavigationHandlers; fires when the WEARER exits nav mode on the glasses. */\n private onGlassesExitCb: (() => void) | null = null\n\n private constructor() {}\n\n public setOnGlassesExit(cb: (() => void) | null): void {\n this.onGlassesExitCb = cb\n }\n\n public static getInstance(): NativeNavigationService {\n if (!NativeNavigationService.instance) {\n NativeNavigationService.instance = new NativeNavigationService()\n }\n return NativeNavigationService.instance\n }\n\n /** True while the glasses' native nav UI owns the display. */\n public get isActive(): boolean {\n return this.active\n }\n\n /**\n * True when the paired glasses render their own nav UI AND this native\n * build exposes the nav-mode functions (both platforms since the G2.kt\n * port — the typeof guard keeps older builds safe).\n */\n public isSupported(): boolean {\n const defaultWearable = useSettingsStore.getState().getSetting(ISLAND_SETTINGS_KEYS.defaultWearable) as\n | DeviceTypes\n | undefined\n // Effective, not model: custom firmware drops hasNativeNavigation so the\n // miniapp's scene HUD owns the display (see effectiveCapabilities).\n const capabilities = getEffectiveCapabilities(defaultWearable || DeviceTypes.NONE)\n return (\n capabilities.hasNativeNavigation === true &&\n typeof (BluetoothSdk as {navigationModeStart?: unknown}).navigationModeStart === \"function\"\n )\n }\n\n /** A trip started (NavigationHandlers.handleStart succeeded). */\n public onTripStart(packageName: string): void {\n if (!this.isSupported() || this.active) return\n console.log(`${LOG_TAG}: entering native nav mode for ${packageName}`)\n this.active = true\n useDisplayStore.getState().setDisplayEvent({layout: {layoutType: \"unavailable\", reason: \"firmware-navigation\"}})\n this.attachListeners()\n void glassesSensorService\n .setNavigationActive(true)\n .then(() => {\n return this.active ? BluetoothSdk.navigationModeStart() : undefined\n })\n .catch((err) => {\n console.error(`${LOG_TAG}: navigationModeStart failed:`, err)\n })\n }\n\n /** The trip ended (arrived / stopped / errored). Safe to call when inactive. */\n public onTripEnd(arrived: boolean): void {\n if (!this.active) return\n console.log(`${LOG_TAG}: exiting native nav mode (arrived=${arrived})`)\n this.teardown()\n void Promise.resolve(BluetoothSdk.navigationModeStop(arrived))\n .then(() => {\n return glassesSensorService.setNavigationActive(false)\n })\n .catch((err) => {\n console.error(`${LOG_TAG}: navigationModeStop failed:`, err)\n })\n }\n\n /**\n * Forward a miniapp NATIVE_NAV payload to the glasses. Returns false when\n * native nav isn't active/supported (the SDK reports \"unsupported\" so the\n * miniapp can skip re-encoding bitmaps it doesn't need).\n */\n public handleMiniappRequest(payload: Record<string, unknown>): boolean {\n if (!this.active || !this.isSupported()) return false\n const action = payload.action\n try {\n switch (action) {\n case \"info\": {\n const info = (payload.info ?? {}) as Partial<NativeNavInfoPayload>\n void BluetoothSdk.navigationUpdateInfo({\n directionIcon: Number(info.directionIcon) || 0,\n distance: String(info.distance ?? \"\"),\n roadName: String(info.roadName ?? \"\"),\n spendTime: String(info.spendTime ?? \"\"),\n remainDistance: String(info.remainDistance ?? \"\"),\n etaTime: String(info.etaTime ?? \"\"),\n speed: String(info.speed ?? \"\"),\n })\n return true\n }\n case \"mini_map\": {\n const map = (payload.map ?? {}) as {data?: unknown; rotationDeg?: unknown; border?: unknown}\n if (typeof map.data !== \"string\" || map.data.length === 0) return false\n void BluetoothSdk.navigationMiniMap({\n data: map.data,\n rotationDeg: Number(map.rotationDeg) || 0,\n border: map.border !== false,\n })\n return true\n }\n case \"overview_map\": {\n const map = (payload.map ?? {}) as {data?: unknown}\n if (typeof map.data !== \"string\" || map.data.length === 0) return false\n void BluetoothSdk.navigationOverviewMap({data: map.data})\n return true\n }\n default:\n console.warn(`${LOG_TAG}: unknown native nav action:`, action)\n return false\n }\n } catch (err) {\n console.error(`${LOG_TAG}: native nav forward failed:`, err)\n return false\n }\n }\n\n private attachListeners(): void {\n // Glasses-side exit ends the whole trip: release the compass override and\n // let NavigationHandlers stop navigation + notify the miniapp (\"cancelled\").\n // Phone-initiated exits (trip already ending) just tear down.\n this.modeSub?.remove()\n this.modeSub = BluetoothSdk.addListener(\"navigation_mode_change\", (event) => {\n if (event.status === \"exited\" && this.active) {\n console.log(`${LOG_TAG}: nav mode exited natively (source=${event.source ?? \"phone\"})`)\n this.teardown()\n if (event.source === \"glasses\") {\n this.onGlassesExitCb?.()\n void glassesSensorService.setNavigationActive(false)\n }\n }\n })\n }\n\n private teardown(): void {\n this.active = false\n this.modeSub?.remove()\n this.modeSub = null\n }\n}\n\nconst nativeNavigationService = NativeNavigationService.getInstance()\nexport default nativeNavigationService\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationHandlers.d.ts","sourceRoot":"","sources":["../../src/services/NavigationHandlers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH,OAAO,EAAC,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAIzF;;;GAGG;AACH,KAAK,aAAa,GAAG,CACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE;IAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAC,KAClF,IAAI,CAAA;AAET;;;GAGG;AACH,KAAK,UAAU,GAAG,CAChB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,EAAE,EAAE,OAAO,EACX,MAAM,CAAC,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,KAC9C,IAAI,CAAA;AAET,qBAAa,kBAAkB;IAO3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAP7B,uEAAuE;IACvE,OAAO,CAAC,YAAY,CAAgC;IACpD,kFAAkF;IAClF,OAAO,CAAC,aAAa,CAAoB;gBAGtB,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU;IAKzC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAgBvB,2FAA2F;IAC3F,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAI1C;;;;;OAKG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQvC;;;;OAIG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAWhC,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"NavigationHandlers.d.ts","sourceRoot":"","sources":["../../src/services/NavigationHandlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -207,7 +207,12 @@ export class NavigationHandlers {
|
|
|
207
207
|
// navigation mode for the duration of the trip.
|
|
208
208
|
nativeNavigationService.onTripStart(packageName);
|
|
209
209
|
}
|
|
210
|
-
|
|
210
|
+
// A refused start (`{ok: false, error}` from the token gate or the
|
|
211
|
+
// native navigator) is request DATA, not a wire failure: the SDK's
|
|
212
|
+
// navigation.start() contract is "resolves {ok, error?}, never throws".
|
|
213
|
+
// Sending it as ok:false on the wire made the SDK reject with its
|
|
214
|
+
// generic "Unknown error" and drop the real message.
|
|
215
|
+
this.sendResult(packageName, requestId, true, result);
|
|
211
216
|
}
|
|
212
217
|
catch (err) {
|
|
213
218
|
console.error(`${LOG_TAG}: navigation start error:`, err);
|
|
@@ -230,7 +235,7 @@ export class NavigationHandlers {
|
|
|
230
235
|
nativeNavigationService.onTripEnd(false);
|
|
231
236
|
const navigation = navigationService;
|
|
232
237
|
const result = navigation ? await navigation.stop() : { ok: true };
|
|
233
|
-
this.sendResult(packageName, requestId,
|
|
238
|
+
this.sendResult(packageName, requestId, true, result);
|
|
234
239
|
}
|
|
235
240
|
else {
|
|
236
241
|
this.sendResult(packageName, requestId, true, { ok: true }, undefined);
|
|
@@ -252,7 +257,7 @@ export class NavigationHandlers {
|
|
|
252
257
|
const result = navigation
|
|
253
258
|
? await navigation.simulateDeviation(offsetMeters)
|
|
254
259
|
: { ok: false, error: "navigation adapter not configured" };
|
|
255
|
-
this.sendResult(packageName, requestId,
|
|
260
|
+
this.sendResult(packageName, requestId, true, result);
|
|
256
261
|
}
|
|
257
262
|
catch (err) {
|
|
258
263
|
console.error(`${LOG_TAG}: navigation deviate error:`, err);
|
|
@@ -269,7 +274,7 @@ export class NavigationHandlers {
|
|
|
269
274
|
const result = navigation
|
|
270
275
|
? await navigation.setWrongSidewalkOffset(enabled)
|
|
271
276
|
: { ok: false, error: "navigation adapter not configured" };
|
|
272
|
-
this.sendResult(packageName, requestId,
|
|
277
|
+
this.sendResult(packageName, requestId, true, result);
|
|
273
278
|
}
|
|
274
279
|
catch (err) {
|
|
275
280
|
console.error(`${LOG_TAG}: navigation setWrongSidewalkOffset error:`, err);
|
|
@@ -286,7 +291,7 @@ export class NavigationHandlers {
|
|
|
286
291
|
const result = navigation
|
|
287
292
|
? await navigation.setSkipCrossings(enabled)
|
|
288
293
|
: { ok: false, error: "navigation adapter not configured" };
|
|
289
|
-
this.sendResult(packageName, requestId,
|
|
294
|
+
this.sendResult(packageName, requestId, true, result);
|
|
290
295
|
}
|
|
291
296
|
catch (err) {
|
|
292
297
|
console.error(`${LOG_TAG}: navigation setSkipCrossings error:`, err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavigationHandlers.js","sourceRoot":"","sources":["../../src/services/NavigationHandlers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * NavigationHandlers — turn-by-turn navigation request handlers for\n * LocalMiniappRuntime. Extracted from LocalMiniappRuntime so the\n * navigation surface (Google Maps Navigation SDK adapter, multi-stop\n * routes, deviation simulator, dev toggles, road-snapped GPS streaming)\n * lives in one file the reviewer can read in isolation.\n *\n * Wire-up: LocalMiniappRuntime owns one instance, constructed with\n * callbacks for sending results / events back to the miniapp. The\n * dispatcher's switch statement delegates each `NAVIGATION_*` case to a\n * handler here. Cross-cutting hooks (cleanup on disconnect, location-\n * stream gating during a trip) are exposed via {@link onDisconnect} and\n * {@link isTripActive}.\n *\n * State owned here:\n * - navListeners: per-package unsubscribers for the nav-update +\n * road-snapped-location + route streams. Detached on disconnect,\n * reattached on the next NAVIGATION_START from the same package.\n * - activeNavApps: packages with a live nav session. Used by the\n * dispatcher to gate raw background-GPS forwards (we don't want the\n * unsnapped fix interleaving with the simulator's snapped output\n * during a trip).\n */\n\nimport {type NavLocation, type NavRoute, type NavUpdate} from \"../runtime/config\"\nimport {cloudClientService} from \"./CloudClientService\"\nimport nativeNavigationService from \"./NativeNavigationService\"\nimport navigationService from \"./NavigationService\"\nimport {MiniappErrorCode, MiniappResponseType, MiniappStreamType} from \"@glassly/miniapp\"\n\nconst LOG_TAG = \"LocalMiniappRuntime\"\n\n/**\n * Shape of the per-miniapp envelope sender — matches\n * LocalMiniappRuntime.sendToMiniapp's signature.\n */\ntype SendToMiniapp = (\n packageName: string,\n envelope: {type: MiniappResponseType; streamType?: MiniappStreamType; data?: unknown},\n) => void\n\n/**\n * Shape of the request-result sender — matches\n * LocalMiniappRuntime.sendResult's signature.\n */\ntype SendResult = (\n packageName: string,\n requestId: string | undefined,\n ok: boolean,\n result?: unknown,\n error?: {code: MiniappErrorCode; message: string},\n) => void\n\nexport class NavigationHandlers {\n /** packageName → unsubscribe fn for that app's nav event forwarder. */\n private navListeners = new Map<string, () => void>()\n /** Set of packageNames that have called navigation.start() and not yet stop(). */\n private activeNavApps = new Set<string>()\n\n constructor(\n private readonly sendToMiniapp: SendToMiniapp,\n private readonly sendResult: SendResult,\n ) {\n nativeNavigationService.setOnGlassesExit(() => this.stopFromGlasses())\n }\n\n /**\n * The wearer exited nav mode on the glasses — end the trip: stop the native\n * navigator and tell each active nav app via a \"cancelled\" update so it can\n * reset its own trip state.\n */\n private stopFromGlasses(): void {\n if (this.activeNavApps.size === 0) return\n console.log(`${LOG_TAG}: nav mode exited on glasses — stopping trip for ${[...this.activeNavApps].join(\", \")}`)\n for (const packageName of this.activeNavApps) {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.NAVIGATION_UPDATE,\n data: {kind: \"cancelled\", reason: \"glasses\"},\n })\n }\n this.activeNavApps.clear()\n void navigationService.stop().catch((err: unknown) => {\n console.error(`${LOG_TAG}: navigation stop after glasses exit failed:`, err)\n })\n }\n\n /** True iff a trip is currently active for the package (used to gate raw-GPS forwards). */\n isTripActive(packageName: string): boolean {\n return this.activeNavApps.has(packageName)\n }\n\n /**\n * Detach the per-app nav event forwarder. Called when the mini-app\n * disconnects. The native nav session is left running so the user can\n * reopen the app and reattach without losing their trip; `activeNavApps`\n * is kept intact for the same reason.\n */\n onDisconnect(packageName: string): void {\n const unsub = this.navListeners.get(packageName)\n if (unsub) {\n unsub()\n this.navListeners.delete(packageName)\n }\n }\n\n /**\n * The user closed/disabled the mini-app (not a crash-respawn). Unlike\n * {@link onDisconnect}, this ends the trip: the glasses leave native nav\n * mode and the phone navigator stops once no other app is navigating.\n */\n onAppClosed(packageName: string): void {\n this.onDisconnect(packageName)\n if (!this.activeNavApps.delete(packageName)) return\n if (this.activeNavApps.size > 0) return\n console.log(`${LOG_TAG}: ${packageName} closed with an active trip — stopping navigation`)\n nativeNavigationService.onTripEnd(false)\n void navigationService.stop().catch((err: unknown) => {\n console.error(`${LOG_TAG}: navigation stop after app close failed:`, err)\n })\n }\n\n async handleStart(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n console.log(`${LOG_TAG}: handleNavigationStart from ${packageName}`, JSON.stringify(payload))\n\n // v2 wire shape sends `stops`; v1 shape sends bare lat/lng. Accept both.\n const rawStops = payload.stops as Array<{lat?: unknown; lng?: unknown}> | undefined\n const stops: Array<{lat: number; lng: number}> = []\n if (Array.isArray(rawStops)) {\n for (const s of rawStops) {\n const sLat = Number(s?.lat)\n const sLng = Number(s?.lng)\n if (Number.isFinite(sLat) && Number.isFinite(sLng)) stops.push({lat: sLat, lng: sLng})\n }\n }\n if (stops.length === 0) {\n const lat = Number(payload.lat)\n const lng = Number(payload.lng)\n if (Number.isFinite(lat) && Number.isFinite(lng)) stops.push({lat, lng})\n }\n if (stops.length === 0) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"stops or lat/lng required\",\n })\n return\n }\n const lat = stops[0].lat\n const lng = stops[0].lng\n const simulate = payload.simulate === true\n const speedNum = Number(payload.speedMultiplier)\n const speedMultiplier = Number.isFinite(speedNum) && speedNum > 0 ? speedNum : 5\n const mode = typeof payload.mode === \"string\" ? payload.mode : \"driving\"\n const avoidRaw = payload.avoid as Record<string, unknown> | undefined\n const avoid = avoidRaw\n ? {\n highways: avoidRaw.highways === true,\n tolls: avoidRaw.tolls === true,\n ferries: avoidRaw.ferries === true,\n }\n : undefined\n const missedRaw = Number(payload.missedTurnRerouteMeters)\n const missedTurnRerouteMeters = Number.isFinite(missedRaw) && missedRaw > 0 ? missedRaw : undefined\n\n const navigation = navigationService\n if (!navigation) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"navigation adapter not configured on host\",\n })\n return\n }\n\n // Reattach the per-app event forwarder (it may have been detached when the\n // mini-app closed its UI without stopping the trip).\n if (!this.navListeners.has(packageName)) {\n const unsubNav = navigation.addListener((update: NavUpdate) => {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.NAVIGATION_UPDATE,\n data: update,\n })\n // Trip ended naturally — keep the forwarder alive (miniapp may\n // restart nav) but remove from active set so stop() accounting\n // stays accurate.\n if (update.kind === \"arrived\" || update.kind === \"error\") {\n this.activeNavApps.delete(packageName)\n if (this.activeNavApps.size === 0) {\n nativeNavigationService.onTripEnd(update.kind === \"arrived\")\n }\n }\n })\n // Forward the nav-SDK's road-snapped GPS fixes as a location_update\n // stream, so the miniapp's existing session.events.onLocation(...) just\n // works while a trip is active.\n const unsubLoc = navigation.addLocationListener((loc: NavLocation) => {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.LOCATION_UPDATE,\n data: {\n lat: loc.lat,\n lng: loc.lng,\n accuracy: loc.accuracy ?? undefined,\n timestamp: loc.timestamp,\n },\n })\n })\n const unsubRoute = navigation.addRouteListener((route: NavRoute) => {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.NAVIGATION_ROUTE,\n data: route,\n })\n })\n this.navListeners.set(packageName, () => {\n unsubNav()\n unsubLoc()\n unsubRoute()\n })\n }\n\n // If a trip is already active for this app (user closed the UI and came\n // back), reuse the running session — replay current snapshot and return\n // ok without restarting the native navigator.\n if (this.activeNavApps.has(packageName) && navigation.getState() !== \"idle\") {\n console.log(`${LOG_TAG}: resuming existing nav session for ${packageName}`)\n const snapshot = navigation.getSnapshot()\n this.sendResult(packageName, requestId, true, {ok: true, resumed: true, snapshot})\n return\n }\n\n try {\n const result = await navigation.start(\n {lat, lng},\n {simulate, speedMultiplier, stops, mode, avoid, missedTurnRerouteMeters},\n )\n if (result.ok) {\n this.activeNavApps.add(packageName)\n // Glasses with a firmware-rendered nav UI (G2) enter their native\n // navigation mode for the duration of the trip.\n nativeNavigationService.onTripStart(packageName)\n }\n this.sendResult(packageName, requestId, result.ok, result, undefined)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation start error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation start error\",\n })\n }\n }\n\n async handleStop(packageName: string, requestId?: string): Promise<void> {\n try {\n const unsub = this.navListeners.get(packageName)\n if (unsub) {\n unsub()\n this.navListeners.delete(packageName)\n }\n this.activeNavApps.delete(packageName)\n // Only stop the native trip when no other miniapp is still navigating.\n if (this.activeNavApps.size === 0) {\n nativeNavigationService.onTripEnd(false)\n const navigation = navigationService\n const result = navigation ? await navigation.stop() : {ok: true}\n this.sendResult(packageName, requestId, result.ok, result, undefined)\n } else {\n this.sendResult(packageName, requestId, true, {ok: true}, undefined)\n }\n } catch (err) {\n console.error(`${LOG_TAG}: navigation stop error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation stop error\",\n })\n }\n }\n\n async handleDeviate(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n const offsetNum = Number(payload.offsetMeters)\n const offsetMeters = Number.isFinite(offsetNum) && offsetNum > 0 ? offsetNum : 20\n const navigation = navigationService\n const result = navigation\n ? await navigation.simulateDeviation(offsetMeters)\n : {ok: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, result.ok, result, undefined)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation deviate error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation deviate error\",\n })\n }\n }\n\n async handleSetWrongSidewalk(\n packageName: string,\n payload: Record<string, unknown>,\n requestId?: string,\n ): Promise<void> {\n try {\n const enabled = payload.enabled === true\n const navigation = navigationService\n const result = navigation\n ? await navigation.setWrongSidewalkOffset(enabled)\n : {ok: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, result.ok, result, undefined)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation setWrongSidewalkOffset error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation setWrongSidewalkOffset error\",\n })\n }\n }\n\n async handleSetSkipCrossings(\n packageName: string,\n payload: Record<string, unknown>,\n requestId?: string,\n ): Promise<void> {\n try {\n const enabled = payload.enabled === true\n const navigation = navigationService\n const result = navigation\n ? await navigation.setSkipCrossings(enabled)\n : {ok: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, result.ok, result, undefined)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation setSkipCrossings error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation setSkipCrossings error\",\n })\n }\n }\n\n handleGetState(packageName: string, requestId?: string): void {\n const snapshot = navigationService.getSnapshot() ?? null\n this.sendResult(packageName, requestId, true, {state: snapshot})\n }\n\n async handleRequestPermission(packageName: string, requestId?: string): Promise<void> {\n try {\n const navigation = navigationService\n const result = navigation\n ? await navigation.requestPermission()\n : {ok: false, accepted: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, true, result)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation requestPermission error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation requestPermission error\",\n })\n }\n }\n\n async handleComputeRoute(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n // With the user's own Mapbox key (Settings > API Keys), compute\n // on-device so routing works without the cloud and bills their account.\n // Without one, go through the v2 cloud maps proxy — org-token Mapbox\n // usage only ever happens cloud-side.\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.computeRoute(payload)\n if (local.ok) {\n this.sendResult(packageName, requestId, true, {ok: true, routes: local.routes ?? []})\n return\n }\n console.warn(`${LOG_TAG}: local computeRoute failed, falling back to cloud:`, local.error)\n }\n\n // Computed in the v2 cloud (provider-abstracted maps service). The SDK\n // payload shape ({origin, stops, mode, avoid, alternatives}) is the v2\n // DirectionsRequest field-for-field, so it passes straight through.\n const {routes} = await cloudClientService.maps.directions(payload as never)\n this.sendResult(packageName, requestId, true, {ok: true, routes})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation computeRoute error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation computeRoute error\",\n })\n }\n }\n\n /**\n * Reverse-geocode a coordinate into a short road name + full formatted\n * address. Backs the SDK pivot engine's road-name fallback (`road`) and the\n * navigation miniapp's dropped-pin / POI-tap labels (`address`). Always\n * resolves with `{ok, road?, address?}` — a missing road/address is\n * `{ok: true, road: null, address: null}`, not an error.\n */\n async handleReverseGeocode(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n const lat = Number(payload.lat)\n const lng = Number(payload.lng)\n if (!Number.isFinite(lat) || !Number.isFinite(lng)) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"lat/lng required\",\n })\n return\n }\n // With the user's own Mapbox key, resolve on-device so this works\n // without the cloud; otherwise use the v2 cloud maps service.\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.reverseGeocodeRoad({lat, lng})\n if (local.ok) {\n this.sendResult(packageName, requestId, true, {\n ok: true,\n road: local.road ?? null,\n address: local.address ?? null,\n })\n return\n }\n console.warn(`${LOG_TAG}: local reverseGeocode failed, falling back to cloud:`, local.error)\n }\n\n const {road, address} = await cloudClientService.maps.reverseGeocode({lat, lng})\n this.sendResult(packageName, requestId, true, {ok: true, road, address})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation reverseGeocode error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation reverseGeocode error\",\n })\n }\n }\n\n /**\n * Type-ahead place search. Runs on-device against Mapbox Search Box when the\n * user saved their own key (Settings > API Keys) — that key exists precisely\n * so search works without the cloud — and falls back to the v2 cloud maps\n * service otherwise. Resolves `{ok: true, suggestions}` — an empty query or no\n * matches is `{ok: true, suggestions: []}`, not an error.\n */\n async handlePlaceAutocomplete(\n packageName: string,\n payload: Record<string, unknown>,\n requestId?: string,\n ): Promise<void> {\n try {\n const query = typeof payload.query === \"string\" ? payload.query : \"\"\n const sessionToken = typeof payload.sessionToken === \"string\" ? payload.sessionToken : \"\"\n const near = this.parseNear(payload.near)\n\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.placeAutocomplete(query, near, sessionToken)\n if (local.ok) {\n this.sendResult(packageName, requestId, true, {ok: true, suggestions: local.suggestions ?? []})\n return\n }\n // A token is set but the direct call failed (bad key, offline, Mapbox\n // error). Fall through to the cloud rather than failing the search\n // outright.\n console.warn(`${LOG_TAG}: local placeAutocomplete failed, falling back to cloud:`, local.error)\n }\n\n const {suggestions} = await cloudClientService.maps.placeAutocomplete({query, near, sessionToken})\n this.sendResult(packageName, requestId, true, {ok: true, suggestions})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation placeAutocomplete error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation placeAutocomplete error\",\n })\n }\n }\n\n /**\n * Resolve a suggestion (`placeId` + `sessionToken`) to a full place with\n * coordinates. Takes the same on-device-vs-cloud branch as\n * {@link handlePlaceAutocomplete}: the `placeId` and session token come from\n * whichever provider produced the suggestion, so both calls must run against\n * the same one. Resolves `{ok: true, place}`.\n */\n async handlePlaceDetails(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n const placeId = typeof payload.placeId === \"string\" ? payload.placeId : \"\"\n const sessionToken = typeof payload.sessionToken === \"string\" ? payload.sessionToken : \"\"\n if (!placeId) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"placeId required\",\n })\n return\n }\n\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.placeDetails(placeId, sessionToken)\n if (local.ok && local.place) {\n this.sendResult(packageName, requestId, true, {ok: true, place: local.place})\n return\n }\n // Don't fall back to the cloud here: this `placeId` came from a Mapbox\n // Search Box suggestion and is not resolvable by another provider.\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: local.error ?? \"navigation placeDetails error\",\n })\n return\n }\n\n const place = await cloudClientService.maps.placeDetails({placeId, sessionToken})\n this.sendResult(packageName, requestId, true, {ok: true, place})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation placeDetails error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation placeDetails error\",\n })\n }\n }\n\n /** Coerce an inbound `near` payload to a {lat,lng}, or undefined when absent/invalid. */\n private parseNear(raw: unknown): {lat: number; lng: number} | undefined {\n if (!raw || typeof raw !== \"object\") return undefined\n const obj = raw as Record<string, unknown>\n const lat = Number(obj.lat)\n const lng = Number(obj.lng)\n if (!Number.isFinite(lat) || !Number.isFinite(lng)) return undefined\n return {lat, lng}\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"NavigationHandlers.js","sourceRoot":"","sources":["../../src/services/NavigationHandlers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * NavigationHandlers — turn-by-turn navigation request handlers for\n * LocalMiniappRuntime. Extracted from LocalMiniappRuntime so the\n * navigation surface (Google Maps Navigation SDK adapter, multi-stop\n * routes, deviation simulator, dev toggles, road-snapped GPS streaming)\n * lives in one file the reviewer can read in isolation.\n *\n * Wire-up: LocalMiniappRuntime owns one instance, constructed with\n * callbacks for sending results / events back to the miniapp. The\n * dispatcher's switch statement delegates each `NAVIGATION_*` case to a\n * handler here. Cross-cutting hooks (cleanup on disconnect, location-\n * stream gating during a trip) are exposed via {@link onDisconnect} and\n * {@link isTripActive}.\n *\n * State owned here:\n * - navListeners: per-package unsubscribers for the nav-update +\n * road-snapped-location + route streams. Detached on disconnect,\n * reattached on the next NAVIGATION_START from the same package.\n * - activeNavApps: packages with a live nav session. Used by the\n * dispatcher to gate raw background-GPS forwards (we don't want the\n * unsnapped fix interleaving with the simulator's snapped output\n * during a trip).\n */\n\nimport {type NavLocation, type NavRoute, type NavUpdate} from \"../runtime/config\"\nimport {cloudClientService} from \"./CloudClientService\"\nimport nativeNavigationService from \"./NativeNavigationService\"\nimport navigationService from \"./NavigationService\"\nimport {MiniappErrorCode, MiniappResponseType, MiniappStreamType} from \"@glassly/miniapp\"\n\nconst LOG_TAG = \"LocalMiniappRuntime\"\n\n/**\n * Shape of the per-miniapp envelope sender — matches\n * LocalMiniappRuntime.sendToMiniapp's signature.\n */\ntype SendToMiniapp = (\n packageName: string,\n envelope: {type: MiniappResponseType; streamType?: MiniappStreamType; data?: unknown},\n) => void\n\n/**\n * Shape of the request-result sender — matches\n * LocalMiniappRuntime.sendResult's signature.\n */\ntype SendResult = (\n packageName: string,\n requestId: string | undefined,\n ok: boolean,\n result?: unknown,\n error?: {code: MiniappErrorCode; message: string},\n) => void\n\nexport class NavigationHandlers {\n /** packageName → unsubscribe fn for that app's nav event forwarder. */\n private navListeners = new Map<string, () => void>()\n /** Set of packageNames that have called navigation.start() and not yet stop(). */\n private activeNavApps = new Set<string>()\n\n constructor(\n private readonly sendToMiniapp: SendToMiniapp,\n private readonly sendResult: SendResult,\n ) {\n nativeNavigationService.setOnGlassesExit(() => this.stopFromGlasses())\n }\n\n /**\n * The wearer exited nav mode on the glasses — end the trip: stop the native\n * navigator and tell each active nav app via a \"cancelled\" update so it can\n * reset its own trip state.\n */\n private stopFromGlasses(): void {\n if (this.activeNavApps.size === 0) return\n console.log(`${LOG_TAG}: nav mode exited on glasses — stopping trip for ${[...this.activeNavApps].join(\", \")}`)\n for (const packageName of this.activeNavApps) {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.NAVIGATION_UPDATE,\n data: {kind: \"cancelled\", reason: \"glasses\"},\n })\n }\n this.activeNavApps.clear()\n void navigationService.stop().catch((err: unknown) => {\n console.error(`${LOG_TAG}: navigation stop after glasses exit failed:`, err)\n })\n }\n\n /** True iff a trip is currently active for the package (used to gate raw-GPS forwards). */\n isTripActive(packageName: string): boolean {\n return this.activeNavApps.has(packageName)\n }\n\n /**\n * Detach the per-app nav event forwarder. Called when the mini-app\n * disconnects. The native nav session is left running so the user can\n * reopen the app and reattach without losing their trip; `activeNavApps`\n * is kept intact for the same reason.\n */\n onDisconnect(packageName: string): void {\n const unsub = this.navListeners.get(packageName)\n if (unsub) {\n unsub()\n this.navListeners.delete(packageName)\n }\n }\n\n /**\n * The user closed/disabled the mini-app (not a crash-respawn). Unlike\n * {@link onDisconnect}, this ends the trip: the glasses leave native nav\n * mode and the phone navigator stops once no other app is navigating.\n */\n onAppClosed(packageName: string): void {\n this.onDisconnect(packageName)\n if (!this.activeNavApps.delete(packageName)) return\n if (this.activeNavApps.size > 0) return\n console.log(`${LOG_TAG}: ${packageName} closed with an active trip — stopping navigation`)\n nativeNavigationService.onTripEnd(false)\n void navigationService.stop().catch((err: unknown) => {\n console.error(`${LOG_TAG}: navigation stop after app close failed:`, err)\n })\n }\n\n async handleStart(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n console.log(`${LOG_TAG}: handleNavigationStart from ${packageName}`, JSON.stringify(payload))\n\n // v2 wire shape sends `stops`; v1 shape sends bare lat/lng. Accept both.\n const rawStops = payload.stops as Array<{lat?: unknown; lng?: unknown}> | undefined\n const stops: Array<{lat: number; lng: number}> = []\n if (Array.isArray(rawStops)) {\n for (const s of rawStops) {\n const sLat = Number(s?.lat)\n const sLng = Number(s?.lng)\n if (Number.isFinite(sLat) && Number.isFinite(sLng)) stops.push({lat: sLat, lng: sLng})\n }\n }\n if (stops.length === 0) {\n const lat = Number(payload.lat)\n const lng = Number(payload.lng)\n if (Number.isFinite(lat) && Number.isFinite(lng)) stops.push({lat, lng})\n }\n if (stops.length === 0) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"stops or lat/lng required\",\n })\n return\n }\n const lat = stops[0].lat\n const lng = stops[0].lng\n const simulate = payload.simulate === true\n const speedNum = Number(payload.speedMultiplier)\n const speedMultiplier = Number.isFinite(speedNum) && speedNum > 0 ? speedNum : 5\n const mode = typeof payload.mode === \"string\" ? payload.mode : \"driving\"\n const avoidRaw = payload.avoid as Record<string, unknown> | undefined\n const avoid = avoidRaw\n ? {\n highways: avoidRaw.highways === true,\n tolls: avoidRaw.tolls === true,\n ferries: avoidRaw.ferries === true,\n }\n : undefined\n const missedRaw = Number(payload.missedTurnRerouteMeters)\n const missedTurnRerouteMeters = Number.isFinite(missedRaw) && missedRaw > 0 ? missedRaw : undefined\n\n const navigation = navigationService\n if (!navigation) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"navigation adapter not configured on host\",\n })\n return\n }\n\n // Reattach the per-app event forwarder (it may have been detached when the\n // mini-app closed its UI without stopping the trip).\n if (!this.navListeners.has(packageName)) {\n const unsubNav = navigation.addListener((update: NavUpdate) => {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.NAVIGATION_UPDATE,\n data: update,\n })\n // Trip ended naturally — keep the forwarder alive (miniapp may\n // restart nav) but remove from active set so stop() accounting\n // stays accurate.\n if (update.kind === \"arrived\" || update.kind === \"error\") {\n this.activeNavApps.delete(packageName)\n if (this.activeNavApps.size === 0) {\n nativeNavigationService.onTripEnd(update.kind === \"arrived\")\n }\n }\n })\n // Forward the nav-SDK's road-snapped GPS fixes as a location_update\n // stream, so the miniapp's existing session.events.onLocation(...) just\n // works while a trip is active.\n const unsubLoc = navigation.addLocationListener((loc: NavLocation) => {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.LOCATION_UPDATE,\n data: {\n lat: loc.lat,\n lng: loc.lng,\n accuracy: loc.accuracy ?? undefined,\n timestamp: loc.timestamp,\n },\n })\n })\n const unsubRoute = navigation.addRouteListener((route: NavRoute) => {\n this.sendToMiniapp(packageName, {\n type: MiniappResponseType.EVENT,\n streamType: MiniappStreamType.NAVIGATION_ROUTE,\n data: route,\n })\n })\n this.navListeners.set(packageName, () => {\n unsubNav()\n unsubLoc()\n unsubRoute()\n })\n }\n\n // If a trip is already active for this app (user closed the UI and came\n // back), reuse the running session — replay current snapshot and return\n // ok without restarting the native navigator.\n if (this.activeNavApps.has(packageName) && navigation.getState() !== \"idle\") {\n console.log(`${LOG_TAG}: resuming existing nav session for ${packageName}`)\n const snapshot = navigation.getSnapshot()\n this.sendResult(packageName, requestId, true, {ok: true, resumed: true, snapshot})\n return\n }\n\n try {\n const result = await navigation.start(\n {lat, lng},\n {simulate, speedMultiplier, stops, mode, avoid, missedTurnRerouteMeters},\n )\n if (result.ok) {\n this.activeNavApps.add(packageName)\n // Glasses with a firmware-rendered nav UI (G2) enter their native\n // navigation mode for the duration of the trip.\n nativeNavigationService.onTripStart(packageName)\n }\n // A refused start (`{ok: false, error}` from the token gate or the\n // native navigator) is request DATA, not a wire failure: the SDK's\n // navigation.start() contract is \"resolves {ok, error?}, never throws\".\n // Sending it as ok:false on the wire made the SDK reject with its\n // generic \"Unknown error\" and drop the real message.\n this.sendResult(packageName, requestId, true, result)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation start error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation start error\",\n })\n }\n }\n\n async handleStop(packageName: string, requestId?: string): Promise<void> {\n try {\n const unsub = this.navListeners.get(packageName)\n if (unsub) {\n unsub()\n this.navListeners.delete(packageName)\n }\n this.activeNavApps.delete(packageName)\n // Only stop the native trip when no other miniapp is still navigating.\n if (this.activeNavApps.size === 0) {\n nativeNavigationService.onTripEnd(false)\n const navigation = navigationService\n const result = navigation ? await navigation.stop() : {ok: true}\n this.sendResult(packageName, requestId, true, result)\n } else {\n this.sendResult(packageName, requestId, true, {ok: true}, undefined)\n }\n } catch (err) {\n console.error(`${LOG_TAG}: navigation stop error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation stop error\",\n })\n }\n }\n\n async handleDeviate(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n const offsetNum = Number(payload.offsetMeters)\n const offsetMeters = Number.isFinite(offsetNum) && offsetNum > 0 ? offsetNum : 20\n const navigation = navigationService\n const result = navigation\n ? await navigation.simulateDeviation(offsetMeters)\n : {ok: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, true, result)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation deviate error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation deviate error\",\n })\n }\n }\n\n async handleSetWrongSidewalk(\n packageName: string,\n payload: Record<string, unknown>,\n requestId?: string,\n ): Promise<void> {\n try {\n const enabled = payload.enabled === true\n const navigation = navigationService\n const result = navigation\n ? await navigation.setWrongSidewalkOffset(enabled)\n : {ok: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, true, result)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation setWrongSidewalkOffset error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation setWrongSidewalkOffset error\",\n })\n }\n }\n\n async handleSetSkipCrossings(\n packageName: string,\n payload: Record<string, unknown>,\n requestId?: string,\n ): Promise<void> {\n try {\n const enabled = payload.enabled === true\n const navigation = navigationService\n const result = navigation\n ? await navigation.setSkipCrossings(enabled)\n : {ok: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, true, result)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation setSkipCrossings error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation setSkipCrossings error\",\n })\n }\n }\n\n handleGetState(packageName: string, requestId?: string): void {\n const snapshot = navigationService.getSnapshot() ?? null\n this.sendResult(packageName, requestId, true, {state: snapshot})\n }\n\n async handleRequestPermission(packageName: string, requestId?: string): Promise<void> {\n try {\n const navigation = navigationService\n const result = navigation\n ? await navigation.requestPermission()\n : {ok: false, accepted: false, error: \"navigation adapter not configured\"}\n this.sendResult(packageName, requestId, true, result)\n } catch (err) {\n console.error(`${LOG_TAG}: navigation requestPermission error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation requestPermission error\",\n })\n }\n }\n\n async handleComputeRoute(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n // With the user's own Mapbox key (Settings > API Keys), compute\n // on-device so routing works without the cloud and bills their account.\n // Without one, go through the v2 cloud maps proxy — org-token Mapbox\n // usage only ever happens cloud-side.\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.computeRoute(payload)\n if (local.ok) {\n this.sendResult(packageName, requestId, true, {ok: true, routes: local.routes ?? []})\n return\n }\n console.warn(`${LOG_TAG}: local computeRoute failed, falling back to cloud:`, local.error)\n }\n\n // Computed in the v2 cloud (provider-abstracted maps service). The SDK\n // payload shape ({origin, stops, mode, avoid, alternatives}) is the v2\n // DirectionsRequest field-for-field, so it passes straight through.\n const {routes} = await cloudClientService.maps.directions(payload as never)\n this.sendResult(packageName, requestId, true, {ok: true, routes})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation computeRoute error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation computeRoute error\",\n })\n }\n }\n\n /**\n * Reverse-geocode a coordinate into a short road name + full formatted\n * address. Backs the SDK pivot engine's road-name fallback (`road`) and the\n * navigation miniapp's dropped-pin / POI-tap labels (`address`). Always\n * resolves with `{ok, road?, address?}` — a missing road/address is\n * `{ok: true, road: null, address: null}`, not an error.\n */\n async handleReverseGeocode(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n const lat = Number(payload.lat)\n const lng = Number(payload.lng)\n if (!Number.isFinite(lat) || !Number.isFinite(lng)) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"lat/lng required\",\n })\n return\n }\n // With the user's own Mapbox key, resolve on-device so this works\n // without the cloud; otherwise use the v2 cloud maps service.\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.reverseGeocodeRoad({lat, lng})\n if (local.ok) {\n this.sendResult(packageName, requestId, true, {\n ok: true,\n road: local.road ?? null,\n address: local.address ?? null,\n })\n return\n }\n console.warn(`${LOG_TAG}: local reverseGeocode failed, falling back to cloud:`, local.error)\n }\n\n const {road, address} = await cloudClientService.maps.reverseGeocode({lat, lng})\n this.sendResult(packageName, requestId, true, {ok: true, road, address})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation reverseGeocode error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation reverseGeocode error\",\n })\n }\n }\n\n /**\n * Type-ahead place search. Runs on-device against Mapbox Search Box when the\n * user saved their own key (Settings > API Keys) — that key exists precisely\n * so search works without the cloud — and falls back to the v2 cloud maps\n * service otherwise. Resolves `{ok: true, suggestions}` — an empty query or no\n * matches is `{ok: true, suggestions: []}`, not an error.\n */\n async handlePlaceAutocomplete(\n packageName: string,\n payload: Record<string, unknown>,\n requestId?: string,\n ): Promise<void> {\n try {\n const query = typeof payload.query === \"string\" ? payload.query : \"\"\n const sessionToken = typeof payload.sessionToken === \"string\" ? payload.sessionToken : \"\"\n const near = this.parseNear(payload.near)\n\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.placeAutocomplete(query, near, sessionToken)\n if (local.ok) {\n this.sendResult(packageName, requestId, true, {ok: true, suggestions: local.suggestions ?? []})\n return\n }\n // A token is set but the direct call failed (bad key, offline, Mapbox\n // error). Fall through to the cloud rather than failing the search\n // outright.\n console.warn(`${LOG_TAG}: local placeAutocomplete failed, falling back to cloud:`, local.error)\n }\n\n const {suggestions} = await cloudClientService.maps.placeAutocomplete({query, near, sessionToken})\n this.sendResult(packageName, requestId, true, {ok: true, suggestions})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation placeAutocomplete error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation placeAutocomplete error\",\n })\n }\n }\n\n /**\n * Resolve a suggestion (`placeId` + `sessionToken`) to a full place with\n * coordinates. Takes the same on-device-vs-cloud branch as\n * {@link handlePlaceAutocomplete}: the `placeId` and session token come from\n * whichever provider produced the suggestion, so both calls must run against\n * the same one. Resolves `{ok: true, place}`.\n */\n async handlePlaceDetails(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void> {\n try {\n const placeId = typeof payload.placeId === \"string\" ? payload.placeId : \"\"\n const sessionToken = typeof payload.sessionToken === \"string\" ? payload.sessionToken : \"\"\n if (!placeId) {\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: \"placeId required\",\n })\n return\n }\n\n if (navigationService.hasMapboxToken()) {\n const local = await navigationService.placeDetails(placeId, sessionToken)\n if (local.ok && local.place) {\n this.sendResult(packageName, requestId, true, {ok: true, place: local.place})\n return\n }\n // Don't fall back to the cloud here: this `placeId` came from a Mapbox\n // Search Box suggestion and is not resolvable by another provider.\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: local.error ?? \"navigation placeDetails error\",\n })\n return\n }\n\n const place = await cloudClientService.maps.placeDetails({placeId, sessionToken})\n this.sendResult(packageName, requestId, true, {ok: true, place})\n } catch (err) {\n console.error(`${LOG_TAG}: navigation placeDetails error:`, err)\n this.sendResult(packageName, requestId, false, undefined, {\n code: MiniappErrorCode.INTERNAL,\n message: err instanceof Error ? err.message : \"navigation placeDetails error\",\n })\n }\n }\n\n /** Coerce an inbound `near` payload to a {lat,lng}, or undefined when absent/invalid. */\n private parseNear(raw: unknown): {lat: number; lng: number} | undefined {\n if (!raw || typeof raw !== \"object\") return undefined\n const obj = raw as Record<string, unknown>\n const lat = Number(obj.lat)\n const lng = Number(obj.lng)\n if (!Number.isFinite(lat) || !Number.isFinite(lng)) return undefined\n return {lat, lng}\n }\n}\n"]}
|