@glassly/engine 0.1.0-dev.99 → 0.2.8-dev.445

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.
Files changed (501) hide show
  1. package/README.md +28 -0
  2. package/build/engine.d.ts +32 -10
  3. package/build/engine.d.ts.map +1 -1
  4. package/build/engine.js +24 -16
  5. package/build/engine.js.map +1 -1
  6. package/build/facades/dev.d.ts +9 -0
  7. package/build/facades/dev.d.ts.map +1 -1
  8. package/build/facades/dev.js +9 -0
  9. package/build/facades/dev.js.map +1 -1
  10. package/build/facades/display.d.ts +10 -3
  11. package/build/facades/display.d.ts.map +1 -1
  12. package/build/facades/display.js +22 -8
  13. package/build/facades/display.js.map +1 -1
  14. package/build/facades/displayMirror.d.ts +11 -0
  15. package/build/facades/displayMirror.d.ts.map +1 -1
  16. package/build/facades/displayMirror.js +22 -0
  17. package/build/facades/displayMirror.js.map +1 -1
  18. package/build/facades/glasses.d.ts +31 -1
  19. package/build/facades/glasses.d.ts.map +1 -1
  20. package/build/facades/glasses.js +51 -0
  21. package/build/facades/glasses.js.map +1 -1
  22. package/build/facades/memory.d.ts +0 -6
  23. package/build/facades/memory.d.ts.map +1 -1
  24. package/build/facades/memory.js +1 -9
  25. package/build/facades/memory.js.map +1 -1
  26. package/build/facades/miniapps.d.ts +3 -1
  27. package/build/facades/miniapps.d.ts.map +1 -1
  28. package/build/facades/miniapps.js +3 -1
  29. package/build/facades/miniapps.js.map +1 -1
  30. package/build/facades/pairing.d.ts.map +1 -1
  31. package/build/facades/pairing.js +5 -4
  32. package/build/facades/pairing.js.map +1 -1
  33. package/build/facades/permissions.d.ts +2 -0
  34. package/build/facades/permissions.d.ts.map +1 -1
  35. package/build/facades/permissions.js +48 -0
  36. package/build/facades/permissions.js.map +1 -1
  37. package/build/facades/phoneNotifications.d.ts +20 -9
  38. package/build/facades/phoneNotifications.d.ts.map +1 -1
  39. package/build/facades/phoneNotifications.js +33 -26
  40. package/build/facades/phoneNotifications.js.map +1 -1
  41. package/build/facades/settings.d.ts.map +1 -1
  42. package/build/facades/settings.js +1 -2
  43. package/build/facades/settings.js.map +1 -1
  44. package/build/generated/releaseMetadata.js +4 -4
  45. package/build/generated/releaseMetadata.js.map +1 -1
  46. package/build/index.d.ts +6 -4
  47. package/build/index.d.ts.map +1 -1
  48. package/build/index.js +5 -4
  49. package/build/index.js.map +1 -1
  50. package/build/react/MentraLiveOtaFlow.js +2 -2
  51. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  52. package/build/react/useMentraLiveOta.d.ts.map +1 -1
  53. package/build/react/useMentraLiveOta.js +8 -7
  54. package/build/react/useMentraLiveOta.js.map +1 -1
  55. package/build/runtime/config.d.ts +1 -1
  56. package/build/runtime/config.d.ts.map +1 -1
  57. package/build/runtime/config.js.map +1 -1
  58. package/build/services/AppRegistry.d.ts +4 -1
  59. package/build/services/AppRegistry.d.ts.map +1 -1
  60. package/build/services/AppRegistry.js +21 -1
  61. package/build/services/AppRegistry.js.map +1 -1
  62. package/build/services/BlobStore.d.ts +2 -2
  63. package/build/services/BlobStore.js +3 -3
  64. package/build/services/BlobStore.js.map +1 -1
  65. package/build/services/CloudClientService.d.ts +7 -3
  66. package/build/services/CloudClientService.d.ts.map +1 -1
  67. package/build/services/CloudClientService.js +34 -9
  68. package/build/services/CloudClientService.js.map +1 -1
  69. package/build/services/DevServerBridge.d.ts +1 -18
  70. package/build/services/DevServerBridge.d.ts.map +1 -1
  71. package/build/services/DevServerBridge.js +9 -8
  72. package/build/services/DevServerBridge.js.map +1 -1
  73. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  74. package/build/services/DeviceEventRouter.js +58 -71
  75. package/build/services/DeviceEventRouter.js.map +1 -1
  76. package/build/services/DisplayDiagnostics.d.ts +5 -0
  77. package/build/services/DisplayDiagnostics.d.ts.map +1 -0
  78. package/build/services/DisplayDiagnostics.js +105 -0
  79. package/build/services/DisplayDiagnostics.js.map +1 -0
  80. package/build/services/DisplayProcessor.d.ts +6 -7
  81. package/build/services/DisplayProcessor.d.ts.map +1 -1
  82. package/build/services/DisplayProcessor.js +17 -45
  83. package/build/services/DisplayProcessor.js.map +1 -1
  84. package/build/services/GestureDotsService.d.ts +10 -4
  85. package/build/services/GestureDotsService.d.ts.map +1 -1
  86. package/build/services/GestureDotsService.js +70 -16
  87. package/build/services/GestureDotsService.js.map +1 -1
  88. package/build/services/GlassesKeyboardInput.d.ts +77 -0
  89. package/build/services/GlassesKeyboardInput.d.ts.map +1 -0
  90. package/build/services/GlassesKeyboardInput.js +261 -0
  91. package/build/services/GlassesKeyboardInput.js.map +1 -0
  92. package/build/services/GlassesSensorService.d.ts +47 -0
  93. package/build/services/GlassesSensorService.d.ts.map +1 -0
  94. package/build/services/GlassesSensorService.js +242 -0
  95. package/build/services/GlassesSensorService.js.map +1 -0
  96. package/build/services/GlassesTouchInput.d.ts +14 -0
  97. package/build/services/GlassesTouchInput.d.ts.map +1 -0
  98. package/build/services/GlassesTouchInput.js +107 -0
  99. package/build/services/GlassesTouchInput.js.map +1 -0
  100. package/build/services/HeadingService.d.ts +0 -6
  101. package/build/services/HeadingService.d.ts.map +1 -1
  102. package/build/services/HeadingService.js +0 -27
  103. package/build/services/HeadingService.js.map +1 -1
  104. package/build/services/HotspotShutdown.d.ts.map +1 -1
  105. package/build/services/HotspotShutdown.js +2 -1
  106. package/build/services/HotspotShutdown.js.map +1 -1
  107. package/build/services/JSCrashloopReportService.js +2 -2
  108. package/build/services/JSCrashloopReportService.js.map +1 -1
  109. package/build/services/JSRouter.d.ts +6 -4
  110. package/build/services/JSRouter.d.ts.map +1 -1
  111. package/build/services/JSRouter.js +15 -13
  112. package/build/services/JSRouter.js.map +1 -1
  113. package/build/services/LocalDisplayManager.d.ts +35 -7
  114. package/build/services/LocalDisplayManager.d.ts.map +1 -1
  115. package/build/services/LocalDisplayManager.js +105 -27
  116. package/build/services/LocalDisplayManager.js.map +1 -1
  117. package/build/services/LocalMiniappDataMigration.d.ts +1 -1
  118. package/build/services/LocalMiniappDataMigration.js +1 -1
  119. package/build/services/LocalMiniappDataMigration.js.map +1 -1
  120. package/build/services/LocalMiniappRuntime.d.ts +64 -11
  121. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  122. package/build/services/LocalMiniappRuntime.js +441 -35
  123. package/build/services/LocalMiniappRuntime.js.map +1 -1
  124. package/build/services/LocalSttFallbackCoordinator.d.ts +3 -0
  125. package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
  126. package/build/services/LocalSttFallbackCoordinator.js +27 -8
  127. package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
  128. package/build/services/MemoryStore.d.ts +8 -33
  129. package/build/services/MemoryStore.d.ts.map +1 -1
  130. package/build/services/MemoryStore.js +30 -56
  131. package/build/services/MemoryStore.js.map +1 -1
  132. package/build/services/MiniappEngine.d.ts +3 -3
  133. package/build/services/MiniappEngine.js +7 -7
  134. package/build/services/MiniappEngine.js.map +1 -1
  135. package/build/services/MiniappLauncher.d.ts +8 -0
  136. package/build/services/MiniappLauncher.d.ts.map +1 -1
  137. package/build/services/MiniappLauncher.js +19 -1
  138. package/build/services/MiniappLauncher.js.map +1 -1
  139. package/build/services/MirrorService.d.ts +24 -0
  140. package/build/services/MirrorService.d.ts.map +1 -0
  141. package/build/services/MirrorService.js +132 -0
  142. package/build/services/MirrorService.js.map +1 -0
  143. package/build/services/NativeNavigationService.d.ts +2 -3
  144. package/build/services/NativeNavigationService.d.ts.map +1 -1
  145. package/build/services/NativeNavigationService.js +24 -21
  146. package/build/services/NativeNavigationService.js.map +1 -1
  147. package/build/services/NavigationHandlers.d.ts.map +1 -1
  148. package/build/services/NavigationHandlers.js +10 -5
  149. package/build/services/NavigationHandlers.js.map +1 -1
  150. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  151. package/build/services/OtaInstallCoordinator.js +24 -23
  152. package/build/services/OtaInstallCoordinator.js.map +1 -1
  153. package/build/services/PairedGlassesLatch.d.ts +7 -0
  154. package/build/services/PairedGlassesLatch.d.ts.map +1 -0
  155. package/build/services/PairedGlassesLatch.js +38 -0
  156. package/build/services/PairedGlassesLatch.js.map +1 -0
  157. package/build/services/PhoneActivity.d.ts +23 -0
  158. package/build/services/PhoneActivity.d.ts.map +1 -0
  159. package/build/services/PhoneActivity.js +111 -0
  160. package/build/services/PhoneActivity.js.map +1 -0
  161. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  162. package/build/services/PhoneCameraFovCoordinator.js +4 -3
  163. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  164. package/build/services/PhoneNotificationsSync.d.ts +40 -6
  165. package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
  166. package/build/services/PhoneNotificationsSync.js +160 -84
  167. package/build/services/PhoneNotificationsSync.js.map +1 -1
  168. package/build/services/PhonePhotoCoordinator.d.ts.map +1 -1
  169. package/build/services/PhonePhotoCoordinator.js +6 -5
  170. package/build/services/PhonePhotoCoordinator.js.map +1 -1
  171. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  172. package/build/services/PhoneStreamCoordinator.js +8 -7
  173. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  174. package/build/services/STTModelManager.d.ts +3 -0
  175. package/build/services/STTModelManager.d.ts.map +1 -1
  176. package/build/services/STTModelManager.js +15 -1
  177. package/build/services/STTModelManager.js.map +1 -1
  178. package/build/services/SceneRenderer.d.ts +43 -2
  179. package/build/services/SceneRenderer.d.ts.map +1 -1
  180. package/build/services/SceneRenderer.js +123 -8
  181. package/build/services/SceneRenderer.js.map +1 -1
  182. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  183. package/build/services/StreamLifecycleController.js +6 -14
  184. package/build/services/StreamLifecycleController.js.map +1 -1
  185. package/build/services/TTSModelManager.js +1 -1
  186. package/build/services/TTSModelManager.js.map +1 -1
  187. package/build/services/UIRouter.d.ts +2 -2
  188. package/build/services/UIRouter.js +5 -5
  189. package/build/services/UIRouter.js.map +1 -1
  190. package/build/services/asg/galleryPathMigration.js +1 -1
  191. package/build/services/asg/galleryPathMigration.js.map +1 -1
  192. package/build/services/asg/gallerySyncService.js +2 -2
  193. package/build/services/asg/gallerySyncService.js.map +1 -1
  194. package/build/services/asg/localStorageService.d.ts.map +1 -1
  195. package/build/services/asg/localStorageService.js +3 -3
  196. package/build/services/asg/localStorageService.js.map +1 -1
  197. package/build/services/debug/DashboardOpenTrace.d.ts +32 -0
  198. package/build/services/debug/DashboardOpenTrace.d.ts.map +1 -0
  199. package/build/services/debug/DashboardOpenTrace.js +128 -0
  200. package/build/services/debug/DashboardOpenTrace.js.map +1 -0
  201. package/build/services/debug/dashboardOpenTimeline.d.ts +77 -0
  202. package/build/services/debug/dashboardOpenTimeline.d.ts.map +1 -0
  203. package/build/services/debug/dashboardOpenTimeline.js +195 -0
  204. package/build/services/debug/dashboardOpenTimeline.js.map +1 -0
  205. package/build/services/effectiveCapabilities.d.ts.map +1 -1
  206. package/build/services/effectiveCapabilities.js +25 -13
  207. package/build/services/effectiveCapabilities.js.map +1 -1
  208. package/build/services/gestureClaims.d.ts +34 -15
  209. package/build/services/gestureClaims.d.ts.map +1 -1
  210. package/build/services/gestureClaims.js +42 -21
  211. package/build/services/gestureClaims.js.map +1 -1
  212. package/build/services/manifestFields.d.ts +9 -0
  213. package/build/services/manifestFields.d.ts.map +1 -0
  214. package/build/services/manifestFields.js +26 -0
  215. package/build/services/manifestFields.js.map +1 -0
  216. package/build/services/memoryStoreInstance.d.ts +0 -10
  217. package/build/services/memoryStoreInstance.d.ts.map +1 -1
  218. package/build/services/memoryStoreInstance.js +2 -31
  219. package/build/services/memoryStoreInstance.js.map +1 -1
  220. package/build/services/mirrorSnapshot.d.ts +16 -0
  221. package/build/services/mirrorSnapshot.d.ts.map +1 -0
  222. package/build/services/mirrorSnapshot.js +102 -0
  223. package/build/services/mirrorSnapshot.js.map +1 -0
  224. package/build/services/nativeNavigationGate.d.ts +8 -0
  225. package/build/services/nativeNavigationGate.d.ts.map +1 -0
  226. package/build/services/nativeNavigationGate.js +12 -0
  227. package/build/services/nativeNavigationGate.js.map +1 -0
  228. package/build/services/notificationAppCatalog.d.ts +7 -0
  229. package/build/services/notificationAppCatalog.d.ts.map +1 -0
  230. package/build/services/notificationAppCatalog.js +16 -0
  231. package/build/services/notificationAppCatalog.js.map +1 -0
  232. package/build/services/notifications/notificationPolicy.d.ts +55 -0
  233. package/build/services/notifications/notificationPolicy.d.ts.map +1 -0
  234. package/build/services/notifications/notificationPolicy.js +41 -0
  235. package/build/services/notifications/notificationPolicy.js.map +1 -0
  236. package/build/services/pages/OverlayPages.d.ts +26 -0
  237. package/build/services/pages/OverlayPages.d.ts.map +1 -0
  238. package/build/services/pages/OverlayPages.js +80 -0
  239. package/build/services/pages/OverlayPages.js.map +1 -0
  240. package/build/services/pages/PageHost.d.ts +32 -0
  241. package/build/services/pages/PageHost.d.ts.map +1 -0
  242. package/build/services/pages/PageHost.js +99 -0
  243. package/build/services/pages/PageHost.js.map +1 -0
  244. package/build/services/pages/overlayApps.d.ts +25 -0
  245. package/build/services/pages/overlayApps.d.ts.map +1 -0
  246. package/build/services/pages/overlayApps.js +66 -0
  247. package/build/services/pages/overlayApps.js.map +1 -0
  248. package/build/services/pages/pageEligibility.d.ts +9 -0
  249. package/build/services/pages/pageEligibility.d.ts.map +1 -0
  250. package/build/services/pages/pageEligibility.js +27 -0
  251. package/build/services/pages/pageEligibility.js.map +1 -0
  252. package/build/services/settingsBridge.d.ts +58 -0
  253. package/build/services/settingsBridge.d.ts.map +1 -0
  254. package/build/services/settingsBridge.js +90 -0
  255. package/build/services/settingsBridge.js.map +1 -0
  256. package/build/services/speakerProfileStoreInstance.js +1 -1
  257. package/build/services/speakerProfileStoreInstance.js.map +1 -1
  258. package/build/services/uiShim.d.ts +1 -1
  259. package/build/services/uiShim.js +4 -4
  260. package/build/services/uiShim.js.map +1 -1
  261. package/build/stores/appVisibility.d.ts +28 -0
  262. package/build/stores/appVisibility.d.ts.map +1 -1
  263. package/build/stores/appVisibility.js +34 -0
  264. package/build/stores/appVisibility.js.map +1 -1
  265. package/build/stores/apps.d.ts +13 -0
  266. package/build/stores/apps.d.ts.map +1 -1
  267. package/build/stores/apps.js +66 -12
  268. package/build/stores/apps.js.map +1 -1
  269. package/build/stores/bluetoothSettingKeys.js +1 -1
  270. package/build/stores/bluetoothSettingKeys.js.map +1 -1
  271. package/build/stores/display.d.ts +3 -3
  272. package/build/stores/display.d.ts.map +1 -1
  273. package/build/stores/display.js +16 -4
  274. package/build/stores/display.js.map +1 -1
  275. package/build/stores/glasses.d.ts.map +1 -1
  276. package/build/stores/glasses.js +14 -1
  277. package/build/stores/glasses.js.map +1 -1
  278. package/build/stores/settings.d.ts +1 -0
  279. package/build/stores/settings.d.ts.map +1 -1
  280. package/build/stores/settings.js +170 -44
  281. package/build/stores/settings.js.map +1 -1
  282. package/build/types/applet.d.ts +14 -1
  283. package/build/types/applet.d.ts.map +1 -1
  284. package/build/types/applet.js.map +1 -1
  285. package/build/types/capabilities/even-realities-g2.d.ts.map +1 -1
  286. package/build/types/capabilities/even-realities-g2.js +5 -0
  287. package/build/types/capabilities/even-realities-g2.js.map +1 -1
  288. package/build/types/capabilities/simulated-glasses.d.ts +1 -1
  289. package/build/types/capabilities/simulated-glasses.d.ts.map +1 -1
  290. package/build/types/capabilities/simulated-glasses.js +7 -4
  291. package/build/types/capabilities/simulated-glasses.js.map +1 -1
  292. package/build/types/hardware.d.ts +20 -1
  293. package/build/types/hardware.d.ts.map +1 -1
  294. package/build/types/hardware.js +2 -0
  295. package/build/types/hardware.js.map +1 -1
  296. package/build/types/index.d.ts +1 -0
  297. package/build/types/index.d.ts.map +1 -1
  298. package/build/types/index.js +1 -0
  299. package/build/types/index.js.map +1 -1
  300. package/build/utils/debouncedPatch.d.ts +3 -1
  301. package/build/utils/debouncedPatch.d.ts.map +1 -1
  302. package/build/utils/debouncedPatch.js +6 -3
  303. package/build/utils/debouncedPatch.js.map +1 -1
  304. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  305. package/build/utils/devMiniappLaunch.js +4 -3
  306. package/build/utils/devMiniappLaunch.js.map +1 -1
  307. package/build/utils/display/measurer/TextMeasurer.d.ts +2 -159
  308. package/build/utils/display/measurer/TextMeasurer.d.ts.map +1 -1
  309. package/build/utils/display/measurer/TextMeasurer.js +2 -272
  310. package/build/utils/display/measurer/TextMeasurer.js.map +1 -1
  311. package/build/utils/display/measurer/script-detection.d.ts +1 -52
  312. package/build/utils/display/measurer/script-detection.d.ts.map +1 -1
  313. package/build/utils/display/measurer/script-detection.js +2 -183
  314. package/build/utils/display/measurer/script-detection.js.map +1 -1
  315. package/build/utils/display/pixelArt.d.ts +3 -0
  316. package/build/utils/display/pixelArt.d.ts.map +1 -0
  317. package/build/utils/display/pixelArt.js +3 -0
  318. package/build/utils/display/pixelArt.js.map +1 -0
  319. package/build/utils/display/profiles/g1.d.ts +1 -32
  320. package/build/utils/display/profiles/g1.d.ts.map +1 -1
  321. package/build/utils/display/profiles/g1.js +2 -212
  322. package/build/utils/display/profiles/g1.js.map +1 -1
  323. package/build/utils/display/profiles/g2.d.ts +1 -12
  324. package/build/utils/display/profiles/g2.d.ts.map +1 -1
  325. package/build/utils/display/profiles/g2.js +2 -33
  326. package/build/utils/display/profiles/g2.js.map +1 -1
  327. package/build/utils/display/profiles/nex.d.ts +1 -9
  328. package/build/utils/display/profiles/nex.d.ts.map +1 -1
  329. package/build/utils/display/profiles/nex.js +2 -149
  330. package/build/utils/display/profiles/nex.js.map +1 -1
  331. package/build/utils/display/profiles/types.d.ts +1 -102
  332. package/build/utils/display/profiles/types.d.ts.map +1 -1
  333. package/build/utils/display/profiles/types.js.map +1 -1
  334. package/build/utils/display/profiles/z100.d.ts +1 -32
  335. package/build/utils/display/profiles/z100.d.ts.map +1 -1
  336. package/build/utils/display/profiles/z100.js +2 -181
  337. package/build/utils/display/profiles/z100.js.map +1 -1
  338. package/build/utils/display/scene/degrade.d.ts.map +1 -1
  339. package/build/utils/display/scene/degrade.js +4 -1
  340. package/build/utils/display/scene/degrade.js.map +1 -1
  341. package/build/utils/display/scene/differ.d.ts +13 -1
  342. package/build/utils/display/scene/differ.d.ts.map +1 -1
  343. package/build/utils/display/scene/differ.js +22 -0
  344. package/build/utils/display/scene/differ.js.map +1 -1
  345. package/build/utils/display/scene/index.d.ts +1 -1
  346. package/build/utils/display/scene/index.d.ts.map +1 -1
  347. package/build/utils/display/scene/index.js.map +1 -1
  348. package/build/utils/display/scene/process.d.ts.map +1 -1
  349. package/build/utils/display/scene/process.js +183 -11
  350. package/build/utils/display/scene/process.js.map +1 -1
  351. package/build/utils/display/scene/store.d.ts +1 -1
  352. package/build/utils/display/scene/store.d.ts.map +1 -1
  353. package/build/utils/display/scene/store.js +0 -0
  354. package/build/utils/display/scene/store.js.map +1 -1
  355. package/build/utils/display/scene/svgPath.d.ts +9 -0
  356. package/build/utils/display/scene/svgPath.d.ts.map +1 -0
  357. package/build/utils/display/scene/svgPath.js +167 -0
  358. package/build/utils/display/scene/svgPath.js.map +1 -0
  359. package/build/utils/display/scene/types.d.ts +2 -142
  360. package/build/utils/display/scene/types.d.ts.map +1 -1
  361. package/build/utils/display/scene/types.js +0 -0
  362. package/build/utils/display/scene/types.js.map +1 -1
  363. package/build/utils/display/wrapper/TextWrapper.d.ts +1 -101
  364. package/build/utils/display/wrapper/TextWrapper.d.ts.map +1 -1
  365. package/build/utils/display/wrapper/TextWrapper.js +2 -470
  366. package/build/utils/display/wrapper/TextWrapper.js.map +1 -1
  367. package/build/utils/display/wrapper/types.d.ts +2 -74
  368. package/build/utils/display/wrapper/types.d.ts.map +1 -1
  369. package/build/utils/display/wrapper/types.js +2 -10
  370. package/build/utils/display/wrapper/types.js.map +1 -1
  371. package/build/utils/hardware/hardware.js +1 -1
  372. package/build/utils/hardware/hardware.js.map +1 -1
  373. package/build/utils/timers/timers.d.ts.map +1 -1
  374. package/build/utils/timers/timers.js +26 -4
  375. package/build/utils/timers/timers.js.map +1 -1
  376. package/package.json +8 -8
  377. package/src/engine.ts +24 -15
  378. package/src/facades/dev.ts +10 -0
  379. package/src/facades/display.ts +21 -8
  380. package/src/facades/displayMirror.ts +29 -0
  381. package/src/facades/glasses.ts +61 -1
  382. package/src/facades/memory.ts +1 -12
  383. package/src/facades/miniapps.ts +4 -1
  384. package/src/facades/pairing.ts +8 -6
  385. package/src/facades/permissions.ts +46 -0
  386. package/src/facades/phoneNotifications.ts +45 -26
  387. package/src/facades/settings.ts +1 -2
  388. package/src/generated/releaseMetadata.ts +4 -4
  389. package/src/index.ts +6 -9
  390. package/src/react/MentraLiveOtaFlow.tsx +2 -2
  391. package/src/react/useMentraLiveOta.ts +14 -8
  392. package/src/runtime/config.ts +1 -1
  393. package/src/services/AppRegistry.ts +43 -7
  394. package/src/services/BlobStore.ts +3 -3
  395. package/src/services/CloudClientService.ts +37 -10
  396. package/src/services/DevServerBridge.ts +12 -10
  397. package/src/services/DeviceEventRouter.ts +73 -74
  398. package/src/services/DisplayDiagnostics.ts +107 -0
  399. package/src/services/DisplayProcessor.ts +20 -55
  400. package/src/services/GestureDotsService.ts +77 -16
  401. package/src/services/GlassesKeyboardInput.ts +306 -0
  402. package/src/services/GlassesSensorService.ts +233 -0
  403. package/src/services/GlassesTouchInput.ts +128 -0
  404. package/src/services/HeadingService.ts +0 -24
  405. package/src/services/HotspotShutdown.ts +3 -1
  406. package/src/services/JSCrashloopReportService.ts +2 -2
  407. package/src/services/JSRouter.ts +29 -14
  408. package/src/services/LocalDisplayManager.ts +112 -26
  409. package/src/services/LocalMiniappDataMigration.ts +1 -1
  410. package/src/services/LocalMiniappRuntime.ts +500 -43
  411. package/src/services/LocalSttFallbackCoordinator.ts +28 -7
  412. package/src/services/MemoryStore.ts +32 -80
  413. package/src/services/MiniappEngine.ts +7 -7
  414. package/src/services/MiniappLauncher.ts +25 -1
  415. package/src/services/MirrorService.ts +139 -0
  416. package/src/services/NativeNavigationService.ts +29 -25
  417. package/src/services/NavigationHandlers.ts +10 -5
  418. package/src/services/OtaInstallCoordinator.ts +36 -34
  419. package/src/services/PairedGlassesLatch.ts +39 -0
  420. package/src/services/PhoneActivity.ts +116 -0
  421. package/src/services/PhoneCameraFovCoordinator.ts +6 -4
  422. package/src/services/PhoneNotificationsSync.ts +185 -103
  423. package/src/services/PhonePhotoCoordinator.ts +9 -10
  424. package/src/services/PhoneStreamCoordinator.ts +13 -11
  425. package/src/services/STTModelManager.ts +15 -1
  426. package/src/services/SceneRenderer.ts +148 -10
  427. package/src/services/StreamLifecycleController.ts +9 -7
  428. package/src/services/TTSModelManager.ts +1 -1
  429. package/src/services/UIRouter.ts +5 -5
  430. package/src/services/asg/galleryPathMigration.ts +1 -1
  431. package/src/services/asg/gallerySyncService.ts +2 -2
  432. package/src/services/asg/localStorageService.ts +3 -3
  433. package/src/services/debug/DashboardOpenTrace.ts +153 -0
  434. package/src/services/debug/dashboardOpenTimeline.ts +237 -0
  435. package/src/services/effectiveCapabilities.ts +32 -13
  436. package/src/services/gestureClaims.ts +72 -23
  437. package/src/services/manifestFields.ts +23 -0
  438. package/src/services/memoryStoreInstance.ts +2 -34
  439. package/src/services/mirrorSnapshot.ts +116 -0
  440. package/src/services/nativeNavigationGate.ts +14 -0
  441. package/src/services/notificationAppCatalog.ts +21 -0
  442. package/src/services/notifications/notificationPolicy.ts +87 -0
  443. package/src/services/pages/OverlayPages.ts +86 -0
  444. package/src/services/pages/PageHost.ts +116 -0
  445. package/src/services/pages/overlayApps.ts +72 -0
  446. package/src/services/pages/pageEligibility.ts +30 -0
  447. package/src/services/settingsBridge.ts +111 -0
  448. package/src/services/speakerProfileStoreInstance.ts +1 -1
  449. package/src/services/uiShim.ts +4 -4
  450. package/src/stores/appVisibility.ts +45 -0
  451. package/src/stores/apps.ts +110 -32
  452. package/src/stores/bluetoothSettingKeys.ts +1 -1
  453. package/src/stores/display.ts +18 -7
  454. package/src/stores/glasses.ts +15 -1
  455. package/src/stores/settings.ts +175 -51
  456. package/src/types/applet.ts +14 -1
  457. package/src/types/capabilities/even-realities-g2.ts +6 -0
  458. package/src/types/capabilities/simulated-glasses.ts +8 -4
  459. package/src/types/hardware.ts +34 -1
  460. package/src/types/index.ts +1 -0
  461. package/src/utils/debouncedPatch.ts +8 -4
  462. package/src/utils/devMiniappLaunch.ts +5 -3
  463. package/src/utils/display/measurer/TextMeasurer.ts +3 -346
  464. package/src/utils/display/measurer/script-detection.ts +10 -218
  465. package/src/utils/display/pixelArt.ts +3 -0
  466. package/src/utils/display/profiles/g1.ts +2 -236
  467. package/src/utils/display/profiles/g2.ts +2 -39
  468. package/src/utils/display/profiles/nex.ts +2 -166
  469. package/src/utils/display/profiles/types.ts +9 -132
  470. package/src/utils/display/profiles/z100.ts +2 -198
  471. package/src/utils/display/scene/degrade.ts +4 -1
  472. package/src/utils/display/scene/differ.ts +25 -1
  473. package/src/utils/display/scene/index.ts +5 -0
  474. package/src/utils/display/scene/process.ts +196 -13
  475. package/src/utils/display/scene/store.ts +0 -0
  476. package/src/utils/display/scene/svgPath.ts +163 -0
  477. package/src/utils/display/scene/types.ts +0 -0
  478. package/src/utils/display/wrapper/TextWrapper.ts +2 -546
  479. package/src/utils/display/wrapper/types.ts +3 -102
  480. package/src/utils/hardware/hardware.ts +1 -1
  481. package/src/utils/timers/timers.ts +32 -4
  482. package/build/services/CustomDashboardModel.d.ts +0 -48
  483. package/build/services/CustomDashboardModel.d.ts.map +0 -1
  484. package/build/services/CustomDashboardModel.js +0 -73
  485. package/build/services/CustomDashboardModel.js.map +0 -1
  486. package/build/services/CustomDashboardService.d.ts +0 -63
  487. package/build/services/CustomDashboardService.d.ts.map +0 -1
  488. package/build/services/CustomDashboardService.js +0 -576
  489. package/build/services/CustomDashboardService.js.map +0 -1
  490. package/build/services/DashboardCoordinator.d.ts +0 -26
  491. package/build/services/DashboardCoordinator.d.ts.map +0 -1
  492. package/build/services/DashboardCoordinator.js +0 -125
  493. package/build/services/DashboardCoordinator.js.map +0 -1
  494. package/build/services/iosNotificationAppCatalog.d.ts +0 -13
  495. package/build/services/iosNotificationAppCatalog.d.ts.map +0 -1
  496. package/build/services/iosNotificationAppCatalog.js +0 -28
  497. package/build/services/iosNotificationAppCatalog.js.map +0 -1
  498. package/src/services/CustomDashboardModel.ts +0 -83
  499. package/src/services/CustomDashboardService.ts +0 -598
  500. package/src/services/DashboardCoordinator.ts +0 -121
  501. package/src/services/iosNotificationAppCatalog.ts +0 -39
@@ -46,6 +46,7 @@ class LocalSttFallbackCoordinator {
46
46
  */
47
47
  private cloudConnected = true
48
48
  private localActive = false
49
+ private starting: Promise<void> | null = null
49
50
  private cloudAdapterAttached = false
50
51
  /**
51
52
  * Soniox-direct (user API key) state, pushed by SonioxDirectService. While
@@ -71,6 +72,17 @@ class LocalSttFallbackCoordinator {
71
72
  // registered a subscription.
72
73
  useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackActive, false)
73
74
  useSettingsStore.getState().setSetting(ISLAND_SETTINGS_KEYS.localSttFallbackReason, "")
75
+ sttModelManager.onModelReady(() => {
76
+ void this.retryAfterModelReady()
77
+ })
78
+ }
79
+
80
+ private async retryAfterModelReady(): Promise<void> {
81
+ // A model can finish downloading while the initial availability check is
82
+ // still pending. Wait for that attempt before retrying so readiness is
83
+ // never lost and native restarts cannot overlap.
84
+ await this.starting
85
+ await this.reconcile()
74
86
  }
75
87
 
76
88
  /**
@@ -170,7 +182,12 @@ class LocalSttFallbackCoordinator {
170
182
  this.attachCloudAdapterIfReady()
171
183
  const shouldBeActive = this.shouldUseLocalStt()
172
184
  if (shouldBeActive && !this.localActive) {
173
- await this.startLocalStt()
185
+ if (!this.starting) {
186
+ this.starting = this.startLocalStt().finally(() => {
187
+ this.starting = null
188
+ })
189
+ }
190
+ await this.starting
174
191
  } else if (!shouldBeActive && this.localActive) {
175
192
  this.stopLocalStt(this.hasTranscriptionSubscription ? "primary transcription recovered" : "subscription gone")
176
193
  } else if (shouldBeActive && this.localActive) {
@@ -203,6 +220,14 @@ class LocalSttFallbackCoordinator {
203
220
 
204
221
  private async startLocalStt(): Promise<void> {
205
222
  this.log("starting local stt")
223
+ try {
224
+ await this.activateLocalStt()
225
+ } catch (err) {
226
+ this.log(`local stt startup failed: ${err}`)
227
+ }
228
+ }
229
+
230
+ private async activateLocalStt(): Promise<void> {
206
231
  const modelAvailable = await sttModelManager.isModelAvailable()
207
232
  if (!modelAvailable) {
208
233
  this.log("local stt model is not available yet — skipping activation")
@@ -212,12 +237,8 @@ class LocalSttFallbackCoordinator {
212
237
  this.log("local stt activation skipped: routing changed before start completed")
213
238
  return
214
239
  }
215
- try {
216
- // Direct btsdk call now (was a host restartTranscriber hook).
217
- await BluetoothSdk.restartTranscriber()
218
- } catch (err) {
219
- this.log(`restartTranscriber failed: ${err}`)
220
- }
240
+ // Native rejects unless the recognizer and its processing loop are ready.
241
+ await BluetoothSdk.restartTranscriber()
221
242
  if (!this.shouldUseLocalStt()) {
222
243
  this.log("local stt activation skipped: routing changed during transcriber restart")
223
244
  return
@@ -21,11 +21,18 @@ import type {MemoryEntry, MemoryNoteSource, MemorySession, MemorySummary} from "
21
21
 
22
22
  import {searchMemoryEntries} from "../utils/memory/search"
23
23
 
24
+ import {BgTimer} from "../utils/timers"
25
+
24
26
  const KEY_ROOT = "memory_"
25
27
  const LOG_SUFFIX = "log"
26
28
  const SUMMARY_SUFFIX = "summaries"
27
29
 
28
- /** The pre-memory-layer Assist miniapp whose storage namespace we migrate. */
30
+ /**
31
+ * The pre-memory-layer Assist miniapp whose storage namespace we migrate.
32
+ * Assist now ships as com.glassly.assistant; the timeline it reads is
33
+ * user-scoped (KEY_ROOT below), so the rename needs no second migration and
34
+ * this constant stays pinned to the old namespace.
35
+ */
29
36
  const LEGACY_ASSIST_PACKAGE = "com.tetramo.assistant"
30
37
  const LEGACY_STORAGE_ROOT = "localstorage_"
31
38
  const LEGACY_LOG_KEY = "assistant:session-log"
@@ -36,36 +43,17 @@ const LEGACY_TRANSCRIPT_KEY = "assistant:transcript-log"
36
43
  const LEGACY_NOTES_KEY = "assistant:notes"
37
44
 
38
45
  const HOUR_MS = 60 * 60 * 1000
39
- const DAY_MS = 24 * HOUR_MS
40
-
41
- /**
42
- * How much timeline a tier can SEE. Retention gating is a read window, not a
43
- * delete: pruning always keeps {@link EXTENDED_RETENTION}'s worth of data, and
44
- * the active policy decides how far back reads reach. A lapsed subscriber's
45
- * older timeline is frozen, not lost — upgrading again restores it instantly.
46
- */
47
- export interface MemoryRetentionPolicy {
48
- maxAgeMs: number
49
- maxEntries: number
50
- maxSummaries: number
51
- }
52
-
53
- /** Free-tier visibility: a 14-day rolling window. */
54
- export const STANDARD_RETENTION: MemoryRetentionPolicy = {
55
- maxAgeMs: 14 * DAY_MS,
56
- maxEntries: 4000,
57
- maxSummaries: 24 * 14,
58
- }
59
46
 
60
47
  /**
61
- * Plus/Pro visibility — and the store's PHYSICAL bounds for every tier. The
62
- * entry cap also bounds the write cost — every persist re-serializes the
63
- * whole timeline, so this cap is a perf ceiling as much as a product number.
48
+ * Physical bounds. There is no age cap: the timeline stays until the user
49
+ * deletes it (clear()/removeScope). The entry cap bounds the write cost —
50
+ * every persist re-serializes the whole timeline, so it is a perf ceiling as
51
+ * much as a product number — and the summary cap keeps one row per hour for
52
+ * about half a year of round-the-clock use, far longer at a normal pace.
64
53
  */
65
- export const EXTENDED_RETENTION: MemoryRetentionPolicy = {
66
- maxAgeMs: 180 * DAY_MS,
54
+ export const MEMORY_BOUNDS = {
67
55
  maxEntries: 24_000,
68
- maxSummaries: 24 * 180,
56
+ maxSummaries: 4320,
69
57
  }
70
58
  const QUERY_LIMIT_CAP = 200
71
59
  const QUERY_LIMIT_DEFAULT = 60
@@ -92,13 +80,6 @@ export interface MemoryStoreHooks {
92
80
  * utterance. Set to 0 to persist synchronously (tests).
93
81
  */
94
82
  writeDebounceMs?: number
95
- /**
96
- * Visibility policy resolver, consulted at every read. A function (not a
97
- * value) so the host can flip between STANDARD and EXTENDED as the user's
98
- * subscription changes without rebuilding the store. Absent = standard.
99
- * Never affects what is STORED — pruning is fixed at EXTENDED bounds.
100
- */
101
- getRetention?: () => MemoryRetentionPolicy
102
83
  }
103
84
 
104
85
  export interface MemoryStats {
@@ -132,7 +113,7 @@ export class MemoryStore {
132
113
  private loadPromise: Promise<void> | null = null
133
114
  private readonly changeListeners = new Set<() => void>()
134
115
  /** Pending debounced log write (transcript appends), if any. */
135
- private logFlushTimer: ReturnType<typeof setTimeout> | null = null
116
+ private logFlushTimer: number | null = null
136
117
  private logDirty = false
137
118
 
138
119
  constructor(private readonly hooks: MemoryStoreHooks) {}
@@ -143,7 +124,7 @@ export class MemoryStore {
143
124
  */
144
125
  async flush(): Promise<void> {
145
126
  if (this.logFlushTimer) {
146
- clearTimeout(this.logFlushTimer)
127
+ BgTimer.clearTimeout(this.logFlushTimer)
147
128
  this.logFlushTimer = null
148
129
  }
149
130
  if (this.logDirty) await this.persistLog()
@@ -257,7 +238,7 @@ export class MemoryStore {
257
238
 
258
239
  async addSummary(summary: MemorySummary): Promise<void> {
259
240
  await this.ensureLoaded()
260
- const {maxSummaries} = EXTENDED_RETENTION
241
+ const {maxSummaries} = MEMORY_BOUNDS
261
242
  this.summaries = this.summaries.filter((s) => s.hourStart !== summary.hourStart)
262
243
  this.summaries.push(summary)
263
244
  if (this.summaries.length > maxSummaries) {
@@ -267,35 +248,29 @@ export class MemoryStore {
267
248
  this.emitChanged()
268
249
  }
269
250
 
270
- // === Reads ===
271
- //
272
- // Every read goes through the VISIBLE view: entries inside the active
273
- // tier's window. Older data may still be stored (see prune) — it is frozen,
274
- // not deleted, so an upgrade widens these views instantly.
251
+ // === Reads === (the whole stored timeline; nothing is hidden by age)
275
252
 
276
253
  /** Entries in [sinceMs, untilMs), newest last. */
277
254
  async window(sinceMs: number, untilMs: number = Date.now()): Promise<MemoryEntry[]> {
278
255
  await this.ensureLoaded()
279
- return this.visibleEntries().filter((e) => e.at >= sinceMs && e.at < untilMs)
256
+ return this.entries.filter((e) => e.at >= sinceMs && e.at < untilMs)
280
257
  }
281
258
 
282
259
  /** All note entries, newest first (Settings > Memory list). */
283
260
  async notes(): Promise<MemoryEntry[]> {
284
261
  await this.ensureLoaded()
285
- return this.visibleEntries()
286
- .filter((e) => e.kind === "note")
287
- .sort((a, b) => b.at - a.at)
262
+ return this.entries.filter((e) => e.kind === "note").sort((a, b) => b.at - a.at)
288
263
  }
289
264
 
290
265
  async stats(): Promise<MemoryStats> {
291
266
  await this.ensureLoaded()
292
- const visible = this.visibleEntries()
267
+ const visible = this.entries
293
268
  const noteCount = visible.filter((e) => e.kind === "note").length
294
269
  return {
295
270
  entryCount: visible.length,
296
271
  lineCount: visible.length - noteCount,
297
272
  noteCount,
298
- summaryCount: this.visibleSummaries().filter((s) => s.text.trim()).length,
273
+ summaryCount: this.summaries.filter((s) => s.text.trim()).length,
299
274
  oldestAt: visible.length > 0 ? visible[0].at : null,
300
275
  }
301
276
  }
@@ -304,13 +279,13 @@ export class MemoryStore {
304
279
  async sessionList(): Promise<MemorySession[]> {
305
280
  await this.ensureLoaded()
306
281
  const byHour = new Map<number, MemoryEntry[]>()
307
- for (const e of this.visibleEntries()) {
282
+ for (const e of this.entries) {
308
283
  const h = hourStartOf(e.at)
309
284
  const list = byHour.get(h) ?? []
310
285
  list.push(e)
311
286
  byHour.set(h, list)
312
287
  }
313
- const summaryByHour = new Map(this.visibleSummaries().map((s) => [s.hourStart, s.text]))
288
+ const summaryByHour = new Map(this.summaries.map((s) => [s.hourStart, s.text]))
314
289
  return [...byHour.entries()]
315
290
  .map(([hourStart, entries]) => {
316
291
  entries.sort((a, b) => a.at - b.at)
@@ -355,7 +330,7 @@ export class MemoryStore {
355
330
  }): Promise<{entries: MemoryEntry[]; windowCount: number}> {
356
331
  await this.ensureLoaded()
357
332
  const limit = q.limit && q.limit > 0 ? Math.min(q.limit, QUERY_LIMIT_CAP) : QUERY_LIMIT_DEFAULT
358
- return searchMemoryEntries(this.visibleEntries(), {
333
+ return searchMemoryEntries(this.entries, {
359
334
  sinceMs: q.sinceMs,
360
335
  untilMs: q.untilMs,
361
336
  contains: q.contains,
@@ -366,7 +341,7 @@ export class MemoryStore {
366
341
 
367
342
  async summaryList(): Promise<MemorySummary[]> {
368
343
  await this.ensureLoaded()
369
- return this.visibleSummaries().sort((a, b) => b.hourStart - a.hourStart)
344
+ return [...this.summaries].sort((a, b) => b.hourStart - a.hourStart)
370
345
  }
371
346
 
372
347
  /** Most recent COMPLETED hour with lines but no summary, or null. */
@@ -375,7 +350,7 @@ export class MemoryStore {
375
350
  const currentHour = hourStartOf(nowMs)
376
351
  const summarized = new Set(this.summaries.map((s) => s.hourStart))
377
352
  const hours = new Set<number>()
378
- for (const e of this.visibleEntries()) {
353
+ for (const e of this.entries) {
379
354
  if (e.kind !== "line") continue
380
355
  const h = hourStartOf(e.at)
381
356
  if (h < currentHour && !summarized.has(h)) hours.add(h)
@@ -513,32 +488,9 @@ export class MemoryStore {
513
488
  }
514
489
  }
515
490
 
516
- private retention(): MemoryRetentionPolicy {
517
- return this.hooks.getRetention?.() ?? STANDARD_RETENTION
518
- }
519
-
520
- /** Entries inside the active tier's visibility window, oldest first. */
521
- private visibleEntries(): MemoryEntry[] {
522
- const cutoff = Date.now() - this.retention().maxAgeMs
523
- return this.entries.filter((e) => e.at >= cutoff)
524
- }
525
-
526
- private visibleSummaries(): MemorySummary[] {
527
- const cutoff = Date.now() - this.retention().maxAgeMs
528
- return this.summaries.filter((s) => s.hourStart >= cutoff)
529
- }
530
-
531
- /**
532
- * Physical bounds, ALWAYS the extended policy regardless of tier. A free or
533
- * lapsed user's older timeline stays on disk (reads just can't see past
534
- * their window) so upgrading — or re-upgrading — restores it rather than
535
- * finding it deleted. Deleting remains the user's call: clear()/removeScope
536
- * operate on the physical store.
537
- */
491
+ /** Keep the newest MEMORY_BOUNDS.maxEntries; nothing goes for age — deleting is the user's call. */
538
492
  private prune(): void {
539
- const {maxAgeMs, maxEntries} = EXTENDED_RETENTION
540
- const cutoff = Date.now() - maxAgeMs
541
- this.entries = this.entries.filter((e) => e.at >= cutoff)
493
+ const {maxEntries} = MEMORY_BOUNDS
542
494
  if (this.entries.length > maxEntries) this.entries = this.entries.slice(-maxEntries)
543
495
  }
544
496
 
@@ -560,7 +512,7 @@ export class MemoryStore {
560
512
  }
561
513
  this.logDirty = true
562
514
  if (this.logFlushTimer) return
563
- this.logFlushTimer = setTimeout(() => {
515
+ this.logFlushTimer = BgTimer.setTimeout(() => {
564
516
  this.logFlushTimer = null
565
517
  void this.persistLog().catch((err) =>
566
518
  console.warn("MemoryStore: debounced log write failed:", err instanceof Error ? err.message : err),
@@ -572,7 +524,7 @@ export class MemoryStore {
572
524
  // Any write of the full array satisfies whatever the debounce was holding.
573
525
  this.logDirty = false
574
526
  if (this.logFlushTimer) {
575
- clearTimeout(this.logFlushTimer)
527
+ BgTimer.clearTimeout(this.logFlushTimer)
576
528
  this.logFlushTimer = null
577
529
  }
578
530
  if (this.loadedUserId == null) return
@@ -1,5 +1,5 @@
1
1
  /**
2
- * MiniappEngine — constructs the GlasslyJS router singletons (crash controller,
2
+ * MiniappEngine — constructs the JSRuntime router singletons (crash controller,
3
3
  * UI router, JS router), binds them to the native Crust module + the launcher,
4
4
  * wires the dev-server background-respawn signal, and starts the message pump.
5
5
  *
@@ -40,7 +40,7 @@ function wireDevServerRespawnBackground(router: JSRouter, uiRouter: UIRouter): v
40
40
  // hot-reload.
41
41
  const resolved = await miniappLauncher.resolveBundle(packageName)
42
42
  if (!resolved) {
43
- console.warn(`GlasslyJS: respawn-bg could not resolve bundle for ${packageName}`)
43
+ console.warn(`JSRuntime: respawn-bg could not resolve bundle for ${packageName}`)
44
44
  return
45
45
  }
46
46
  // Force a respawn (kill + spawn) rather than launcher.ensureRunning,
@@ -51,7 +51,7 @@ function wireDevServerRespawnBackground(router: JSRouter, uiRouter: UIRouter): v
51
51
  installedManifest: resolved.installedManifest,
52
52
  })
53
53
  if (!ok) {
54
- console.warn(`GlasslyJS: respawn-bg failed for ${packageName}`)
54
+ console.warn(`JSRuntime: respawn-bg failed for ${packageName}`)
55
55
  return
56
56
  }
57
57
  // The respawned JSContext is a fresh MiniappSession with ui.bound false.
@@ -60,13 +60,13 @@ function wireDevServerRespawnBackground(router: JSRouter, uiRouter: UIRouter): v
60
60
  // instead of being dropped while unbound.
61
61
  uiRouter.notifyReopen(packageName)
62
62
  } catch (e) {
63
- console.warn(`GlasslyJS: respawn-bg threw for ${packageName}:`, e)
63
+ console.warn(`JSRuntime: respawn-bg threw for ${packageName}:`, e)
64
64
  }
65
65
  })
66
66
  }
67
67
 
68
68
  /**
69
- * Construct (once) and return the GlasslyJS engine singletons. Starts the router's
69
+ * Construct (once) and return the JSRuntime engine singletons. Starts the router's
70
70
  * message pump on first call. Subsequent calls return the same instances.
71
71
  */
72
72
  export function ensureMiniappEngine(): MiniappEngine {
@@ -112,7 +112,7 @@ export function ensureMiniappEngine(): MiniappEngine {
112
112
  return engine
113
113
  }
114
114
 
115
- /** Stop the GlasslyJS message pump and tear down router-managed JSContexts. */
115
+ /** Stop the JSRuntime message pump and tear down router-managed JSContexts. */
116
116
  export async function stopMiniappEngine(): Promise<void> {
117
117
  const current = engine
118
118
  if (!current) return
@@ -131,7 +131,7 @@ export async function stopMiniappEngine(): Promise<void> {
131
131
  try {
132
132
  await current.router.unregister(packageName)
133
133
  } catch (err) {
134
- console.warn(`GlasslyJS: failed to unregister ${packageName} during stop:`, err)
134
+ console.warn(`JSRuntime: failed to unregister ${packageName} during stop:`, err)
135
135
  }
136
136
  }),
137
137
  )
@@ -25,11 +25,13 @@
25
25
 
26
26
  import {File} from "expo-file-system"
27
27
 
28
+ import {permissions} from "../facades/permissions"
28
29
  import {decideDevLaunchRoute} from "../utils/devMiniappLaunch"
29
30
  import {storage} from "../utils/storage/storage"
30
31
  import appRegistry, {getLocalAppRunningState, saveLocalAppRunningState} from "./AppRegistry"
31
32
  import devServerBridge from "./DevServerBridge"
32
33
  import localMiniappRuntime, {type InstalledMiniappManifest} from "./LocalMiniappRuntime"
34
+ import type {MiniappLaunchSource} from "@glassly/miniapp"
33
35
  import type {JSRouter} from "./JSRouter"
34
36
 
35
37
  interface LauncherDeps {
@@ -42,6 +44,8 @@ export interface LaunchHints {
42
44
  devUrl?: string
43
45
  version?: string
44
46
  devPort?: string
47
+ /** Who started the app; reported to the miniapp on connect. */
48
+ launchSource?: MiniappLaunchSource
45
49
  }
46
50
 
47
51
  /** Everything the launcher resolved for a package — bg source + UI entry. */
@@ -257,6 +261,7 @@ class MiniappLauncher {
257
261
  const ok = await router.spawnAndRegister(packageName, resolved.bgSource, {
258
262
  permissions: resolved.declaredPermissions,
259
263
  installedManifest: resolved.installedManifest,
264
+ launchSource: hints?.launchSource,
260
265
  })
261
266
  if (!ok) {
262
267
  throw new Error(`MiniappLauncher: spawn failed for ${packageName}`)
@@ -298,6 +303,11 @@ class MiniappLauncher {
298
303
  * Not compatibility-gated: a previously-running background app shouldn't be
299
304
  * dropped just because glasses are momentarily disconnected at boot — it
300
305
  * resumes when they reconnect, same as mid-session.
306
+ *
307
+ * Persistent apps (the dashboard) start whether or not they were running
308
+ * when the app was last killed, and get a switcher card like any other app.
309
+ * Both restore paths skip apps missing required OS permissions without
310
+ * prompting or clearing their saved running/persistent choice.
301
311
  */
302
312
  async autostartLocalMiniapps(): Promise<void> {
303
313
  const apps = await appRegistry.getInstalledMiniapps()
@@ -306,8 +316,22 @@ class MiniappLauncher {
306
316
  // built-ins (`local:false, offline:true`) restore their native running
307
317
  // state elsewhere and have no bundle to launch.
308
318
  if (!app.local) continue
309
- if (!getLocalAppRunningState(app.packageName)) continue
319
+ if (!app.persistent && !getLocalAppRunningState(app.packageName)) continue
310
320
  if (this.isRunning(app.packageName)) continue
321
+ try {
322
+ const missing = await permissions.missingRequired(app.permissions ?? [])
323
+ if (missing.length > 0) {
324
+ console.info(
325
+ `MiniappLauncher: skipping autostart for ${app.packageName} — missing required permissions: ${missing.join(
326
+ ", ",
327
+ )}`,
328
+ )
329
+ continue
330
+ }
331
+ } catch (e) {
332
+ console.warn(`MiniappLauncher: skipping autostart for ${app.packageName} — permission check failed`, e)
333
+ continue
334
+ }
311
335
  try {
312
336
  await this.ensureRunning(app.packageName)
313
337
  } catch (e) {
@@ -0,0 +1,139 @@
1
+ import type {MirrorSnapshot} from "@glassly/miniapp"
2
+
3
+ import {displayMirror} from "../facades/displayMirror"
4
+ import {useDisplayStore} from "../stores/display"
5
+ import {useGlassesStore} from "../stores/glasses"
6
+ import {SETTINGS, useSettingsStore} from "../stores/settings"
7
+ import {DeviceTypes} from "../types"
8
+ import {BgTimer} from "../utils/timers"
9
+ import displayProcessor from "./DisplayProcessor"
10
+ import {getEffectiveCapabilities} from "./effectiveCapabilities"
11
+ import {isGlassesConnected} from "./GlassesReadiness"
12
+ import {buildMirrorSnapshot} from "./mirrorSnapshot"
13
+
14
+ /** One host-wide preview producer, observed only while miniapps subscribe. */
15
+ class MirrorService {
16
+ private revision = 0
17
+ private lastKey = ""
18
+ private lastEvent: unknown
19
+ private snapshot: MirrorSnapshot | null = null
20
+ private model: string | null = null
21
+ private initialized = false
22
+ private listeners = new Set<(snapshot: MirrorSnapshot) => void>()
23
+ private stops: Array<() => void> = []
24
+ private lastEmittedRevision = 0
25
+ private pendingEvent: unknown
26
+ private pendingFrames = 0
27
+ private timer: ReturnType<typeof BgTimer.setTimeout> | null = null
28
+
29
+ private selectedModel(): string | null {
30
+ return (
31
+ (useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key) as string) ||
32
+ useGlassesStore.getState().deviceModel ||
33
+ null
34
+ )
35
+ }
36
+
37
+ initialize(): void {
38
+ if (this.initialized) return
39
+ this.initialized = true
40
+ this.model = this.selectedModel()
41
+ // Keep stale content from a previous pair out of queries, even when no
42
+ // preview is open. No frame serialization runs in these observers.
43
+ const invalidateModel = () => {
44
+ const model = this.selectedModel()
45
+ if (model === this.model) return
46
+ this.model = model
47
+ this.invalidate("device-changed")
48
+ }
49
+ useGlassesStore.subscribe(invalidateModel)
50
+ useSettingsStore.subscribe(invalidateModel)
51
+ }
52
+
53
+ invalidate(reason: string): void {
54
+ useDisplayStore.getState().setDisplayEvent({layout: {layoutType: "unavailable", reason}})
55
+ }
56
+
57
+ current(): MirrorSnapshot {
58
+ this.initialize()
59
+ const gs = useGlassesStore.getState()
60
+ const model = this.selectedModel()
61
+ const event = useDisplayStore.getState().currentEvent
62
+ const connected = isGlassesConnected(gs.connection)
63
+ const canvas = getEffectiveCapabilities((model ?? DeviceTypes.NONE) as DeviceTypes)?.display
64
+ ? displayMirror.canvas()
65
+ : null
66
+ const now = Date.now()
67
+ const key = JSON.stringify([model, connected, canvas, gs.batteryLevel, Math.floor(now / 60000)])
68
+ if (!this.snapshot || event !== this.lastEvent || key !== this.lastKey) {
69
+ this.lastEvent = event
70
+ this.lastKey = key
71
+ this.snapshot = buildMirrorSnapshot(
72
+ {
73
+ event,
74
+ canvas,
75
+ connected,
76
+ model,
77
+ battery: gs.batteryLevel,
78
+ measureChar: (char) => displayProcessor.measureChar(char),
79
+ now,
80
+ },
81
+ ++this.revision,
82
+ )
83
+ }
84
+ return this.snapshot
85
+ }
86
+
87
+ subscribe(cb: (snapshot: MirrorSnapshot) => void): () => void {
88
+ this.initialize()
89
+ this.listeners.add(cb)
90
+ if (this.listeners.size === 1) {
91
+ // Coalesce to the newest state at most every 33ms. The SDK renderer snaps
92
+ // across skipped revisions rather than replaying obsolete transitions.
93
+ const schedule = () => {
94
+ const event = useDisplayStore.getState().currentEvent
95
+ if (event !== this.pendingEvent) {
96
+ this.pendingEvent = event
97
+ this.pendingFrames++
98
+ }
99
+ if (this.timer) return
100
+ this.timer = BgTimer.setTimeout(() => {
101
+ this.timer = null
102
+ let next = this.current()
103
+ if (this.pendingFrames > 1 && next.content.kind === "scene") {
104
+ next = {
105
+ ...next,
106
+ content: {
107
+ ...next.content,
108
+ elements: next.content.elements.map((element) => ({...element, change: "created" as const})),
109
+ },
110
+ }
111
+ }
112
+ this.pendingFrames = 0
113
+ if (next.revision !== this.lastEmittedRevision) {
114
+ this.lastEmittedRevision = next.revision
115
+ for (const listener of this.listeners) listener(next)
116
+ }
117
+ }, 33)
118
+ }
119
+ this.pendingEvent = useDisplayStore.getState().currentEvent
120
+ this.pendingFrames = 0
121
+ this.stops = [
122
+ useDisplayStore.subscribe(schedule),
123
+ useGlassesStore.subscribe(schedule),
124
+ useSettingsStore.subscribe(schedule),
125
+ ]
126
+ const clock = BgTimer.setInterval(schedule, 1000)
127
+ this.stops.push(() => BgTimer.clearInterval(clock))
128
+ }
129
+ return () => {
130
+ this.listeners.delete(cb)
131
+ if (this.listeners.size) return
132
+ this.stops.splice(0).forEach((stop) => stop())
133
+ if (this.timer) BgTimer.clearTimeout(this.timer)
134
+ this.timer = null
135
+ }
136
+ }
137
+ }
138
+
139
+ export const mirrorService = new MirrorService()