@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
@@ -0,0 +1,14 @@
1
+ import { type TouchEvent } from "@glassly/bluetooth-sdk";
2
+ /**
3
+ * Route both real glasses input and phone mirror controls through the same
4
+ * policy. A claimed gesture goes to the app holding the claim, alone; an
5
+ * unclaimed one goes to every subscriber and then the engine's default. The
6
+ * one rule ahead of the claims: an unclaimed double tap on a miniapp whose
7
+ * frame is visibly on the glasses leaves that app, whoever else claimed the
8
+ * gesture — the dashboard's claim is for the empty screen.
9
+ */
10
+ export declare function dispatchTouchEvent(event: TouchEvent): void;
11
+ export declare function resetTouchInput(): void;
12
+ /** Phone mirror input uses the same dashboard/miniapp policy as real glasses. */
13
+ export declare function sendGesture(gestureName: "single_tap" | "tap_start" | "double_tap" | "tap_end" | "tap_then_hold" | "touch_down" | "swipe_up" | "swipe_down"): void;
14
+ //# sourceMappingURL=GlassesTouchInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlassesTouchInput.d.ts","sourceRoot":"","sources":["../../src/services/GlassesTouchInput.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,UAAU,EAAC,MAAM,wBAAwB,CAAA;AA2CpE;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAiD1D;AAED,wBAAgB,eAAe,IAAI,IAAI,CAGtC;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CACzB,WAAW,EACP,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,SAAS,GACT,eAAe,GACf,YAAY,GACZ,UAAU,GACV,YAAY,GACf,IAAI,CAQN"}
@@ -0,0 +1,107 @@
1
+ import { useDisplayStore } from "../stores/display";
2
+ import { DeviceModels } from "@glassly/bluetooth-sdk";
3
+ import BluetoothSdk from "@glassly/bluetooth-sdk/internal";
4
+ import { useAppStatusStore } from "../stores/apps";
5
+ import { useGlassesStore } from "../stores/glasses";
6
+ import { BgTimer } from "../utils/timers";
7
+ import dashboardOpenTrace from "./debug/DashboardOpenTrace";
8
+ import gestureDotsService from "./GestureDotsService";
9
+ import localDisplayManager from "./LocalDisplayManager";
10
+ import localMiniappRuntime from "./LocalMiniappRuntime";
11
+ import { MiniappExitGesture } from "./MiniappExitGesture";
12
+ import nativeNavigationService from "./NativeNavigationService";
13
+ import { isOverlayApp } from "./pages/overlayApps";
14
+ const miniappExitGesture = new MiniappExitGesture({
15
+ getState: () => useAppStatusStore.getState(),
16
+ getVisiblePackageName: () => localDisplayManager.getVisibleMiniappPackageName(),
17
+ beginExitNotice: (packageName, text) => localDisplayManager.beginMiniappExit(packageName, text),
18
+ finishExitNotice: (packageName) => localDisplayManager.finishMiniappExit(packageName),
19
+ cancelExitNotice: (packageName) => localDisplayManager.cancelMiniappExit(packageName),
20
+ setTimeout: (callback, delay) => BgTimer.setTimeout(callback, delay),
21
+ clearTimeout: (timerId) => BgTimer.clearTimeout(timerId),
22
+ });
23
+ // Raw CFW ring reports include every scroll step. Rate-limit scroll actions
24
+ // separately from press/release recognition, using native receipt timestamps
25
+ // so a JS backlog does not collapse otherwise separate gestures.
26
+ const RING_SCROLL_INTERVAL_MS = 100;
27
+ let lastRingScrollAt = null;
28
+ function shouldForwardScroll(event) {
29
+ if (event.deviceModel !== DeviceModels.G2 ||
30
+ event.source !== 2 ||
31
+ (event.gestureName !== "swipe_up" && event.gestureName !== "swipe_down"))
32
+ return true;
33
+ const elapsed = lastRingScrollAt === null ? null : event.timestamp - lastRingScrollAt;
34
+ if (elapsed !== null && elapsed >= 0 && elapsed < RING_SCROLL_INTERVAL_MS)
35
+ return false;
36
+ lastRingScrollAt = event.timestamp;
37
+ return true;
38
+ }
39
+ /**
40
+ * Route both real glasses input and phone mirror controls through the same
41
+ * policy. A claimed gesture goes to the app holding the claim, alone; an
42
+ * unclaimed one goes to every subscriber and then the engine's default. The
43
+ * one rule ahead of the claims: an unclaimed double tap on a miniapp whose
44
+ * frame is visibly on the glasses leaves that app, whoever else claimed the
45
+ * gesture — the dashboard's claim is for the empty screen.
46
+ */
47
+ export function dispatchTouchEvent(event) {
48
+ const gesture = event.gestureName;
49
+ const claimant = localMiniappRuntime.gestureClaimant(gesture);
50
+ if (gesture === "double_tap") {
51
+ // A visible main miniapp opts out of OS exit by registering double tap (the
52
+ // terminal's back-to-menu). The latest claimant still receives it. Otherwise
53
+ // the tap means "leave the app". The controller shows the bounded OS
54
+ // notice first, then uses the normal
55
+ // store stop path (and closes its phone overlay).
56
+ const visible = localDisplayManager.getVisibleMiniappPackageName();
57
+ if (visible !== null &&
58
+ !localMiniappRuntime.hasGestureClaim(visible, gesture) &&
59
+ miniappExitGesture.tryExitVisibleMiniapp()) {
60
+ gestureDotsService.noteGesture(gesture, true);
61
+ return;
62
+ }
63
+ }
64
+ if (claimant !== null) {
65
+ // An overlay app claims the double tap on an empty screen to open the dashboard.
66
+ if (gesture === "double_tap" && isOverlayApp(claimant))
67
+ dashboardOpenTrace.trigger("double-tap", event.timestamp);
68
+ // The press may have started before this app claimed its release edge.
69
+ gestureDotsService.noteGesture(gesture, true);
70
+ if (!shouldForwardScroll(event))
71
+ return;
72
+ localMiniappRuntime.forwardEvent("touch_event", event, undefined, claimant);
73
+ return;
74
+ }
75
+ // Gesture-dots debug indicator (any device, gated by its setting). It
76
+ // only paints while the screen is otherwise empty. Process even suppressed
77
+ // scroll repeats here so their completion still clears a held dot.
78
+ gestureDotsService.noteGesture(gesture);
79
+ if (!shouldForwardScroll(event))
80
+ return;
81
+ localMiniappRuntime.forwardEvent("touch_event", event);
82
+ // Nobody claimed a double tap: the glasses' own dashboard. On eligible
83
+ // Glassly CFW glasses the dashboard miniapp claims it while it runs
84
+ // (ADR-0006); stock firmware keeps its native dashboard (ADR-0002). The
85
+ // modal nav UI owns the screen; showDashboard would fight it.
86
+ if (gesture === "double_tap" && !nativeNavigationService.isActive) {
87
+ useDisplayStore.getState().setDisplayEvent({ layout: { layoutType: "unavailable", reason: "firmware-dashboard" } });
88
+ void Promise.resolve(BluetoothSdk.showDashboard()).catch((err) => {
89
+ console.error("DeviceEventRouter: showDashboard failed:", err);
90
+ });
91
+ }
92
+ }
93
+ export function resetTouchInput() {
94
+ miniappExitGesture.reset();
95
+ lastRingScrollAt = null;
96
+ }
97
+ /** Phone mirror input uses the same dashboard/miniapp policy as real glasses. */
98
+ export function sendGesture(gestureName) {
99
+ const model = useGlassesStore.getState().deviceModel;
100
+ dispatchTouchEvent({
101
+ type: "touch_event",
102
+ gestureName,
103
+ deviceModel: Object.values(DeviceModels).find((candidate) => candidate === model) ?? DeviceModels.Simulated,
104
+ timestamp: Date.now(),
105
+ });
106
+ }
107
+ //# sourceMappingURL=GlassesTouchInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlassesTouchInput.js","sourceRoot":"","sources":["../../src/services/GlassesTouchInput.ts"],"names":[],"mappings":"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","sourcesContent":["import {useDisplayStore} from \"../stores/display\"\nimport {DeviceModels, type TouchEvent} from \"@glassly/bluetooth-sdk\"\nimport BluetoothSdk from \"@glassly/bluetooth-sdk/internal\"\n\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport dashboardOpenTrace from \"./debug/DashboardOpenTrace\"\nimport gestureDotsService from \"./GestureDotsService\"\nimport localDisplayManager from \"./LocalDisplayManager\"\nimport localMiniappRuntime from \"./LocalMiniappRuntime\"\nimport {MiniappExitGesture} from \"./MiniappExitGesture\"\nimport nativeNavigationService from \"./NativeNavigationService\"\nimport {isOverlayApp} from \"./pages/overlayApps\"\n\nconst miniappExitGesture = new MiniappExitGesture({\n getState: () => useAppStatusStore.getState(),\n getVisiblePackageName: () => localDisplayManager.getVisibleMiniappPackageName(),\n beginExitNotice: (packageName, text) => localDisplayManager.beginMiniappExit(packageName, text),\n finishExitNotice: (packageName) => localDisplayManager.finishMiniappExit(packageName),\n cancelExitNotice: (packageName) => localDisplayManager.cancelMiniappExit(packageName),\n setTimeout: (callback, delay) => BgTimer.setTimeout(callback, delay),\n clearTimeout: (timerId) => BgTimer.clearTimeout(timerId),\n})\n\n// Raw CFW ring reports include every scroll step. Rate-limit scroll actions\n// separately from press/release recognition, using native receipt timestamps\n// so a JS backlog does not collapse otherwise separate gestures.\nconst RING_SCROLL_INTERVAL_MS = 100\nlet lastRingScrollAt: number | null = null\n\nfunction shouldForwardScroll(event: TouchEvent): boolean {\n if (\n event.deviceModel !== DeviceModels.G2 ||\n event.source !== 2 ||\n (event.gestureName !== \"swipe_up\" && event.gestureName !== \"swipe_down\")\n )\n return true\n const elapsed = lastRingScrollAt === null ? null : event.timestamp - lastRingScrollAt\n if (elapsed !== null && elapsed >= 0 && elapsed < RING_SCROLL_INTERVAL_MS) return false\n lastRingScrollAt = event.timestamp\n return true\n}\n\n/**\n * Route both real glasses input and phone mirror controls through the same\n * policy. A claimed gesture goes to the app holding the claim, alone; an\n * unclaimed one goes to every subscriber and then the engine's default. The\n * one rule ahead of the claims: an unclaimed double tap on a miniapp whose\n * frame is visibly on the glasses leaves that app, whoever else claimed the\n * gesture — the dashboard's claim is for the empty screen.\n */\nexport function dispatchTouchEvent(event: TouchEvent): void {\n const gesture = event.gestureName\n const claimant = localMiniappRuntime.gestureClaimant(gesture)\n\n if (gesture === \"double_tap\") {\n // A visible main miniapp opts out of OS exit by registering double tap (the\n // terminal's back-to-menu). The latest claimant still receives it. Otherwise\n // the tap means \"leave the app\". The controller shows the bounded OS\n // notice first, then uses the normal\n // store stop path (and closes its phone overlay).\n const visible = localDisplayManager.getVisibleMiniappPackageName()\n if (\n visible !== null &&\n !localMiniappRuntime.hasGestureClaim(visible, gesture) &&\n miniappExitGesture.tryExitVisibleMiniapp()\n ) {\n gestureDotsService.noteGesture(gesture, true)\n return\n }\n }\n\n if (claimant !== null) {\n // An overlay app claims the double tap on an empty screen to open the dashboard.\n if (gesture === \"double_tap\" && isOverlayApp(claimant)) dashboardOpenTrace.trigger(\"double-tap\", event.timestamp)\n // The press may have started before this app claimed its release edge.\n gestureDotsService.noteGesture(gesture, true)\n if (!shouldForwardScroll(event)) return\n localMiniappRuntime.forwardEvent(\"touch_event\", event, undefined, claimant)\n return\n }\n\n // Gesture-dots debug indicator (any device, gated by its setting). It\n // only paints while the screen is otherwise empty. Process even suppressed\n // scroll repeats here so their completion still clears a held dot.\n gestureDotsService.noteGesture(gesture)\n\n if (!shouldForwardScroll(event)) return\n localMiniappRuntime.forwardEvent(\"touch_event\", event)\n\n // Nobody claimed a double tap: the glasses' own dashboard. On eligible\n // Glassly CFW glasses the dashboard miniapp claims it while it runs\n // (ADR-0006); stock firmware keeps its native dashboard (ADR-0002). The\n // modal nav UI owns the screen; showDashboard would fight it.\n if (gesture === \"double_tap\" && !nativeNavigationService.isActive) {\n useDisplayStore.getState().setDisplayEvent({layout: {layoutType: \"unavailable\", reason: \"firmware-dashboard\"}})\n void Promise.resolve(BluetoothSdk.showDashboard()).catch((err) => {\n console.error(\"DeviceEventRouter: showDashboard failed:\", err)\n })\n }\n}\n\nexport function resetTouchInput(): void {\n miniappExitGesture.reset()\n lastRingScrollAt = null\n}\n\n/** Phone mirror input uses the same dashboard/miniapp policy as real glasses. */\nexport function sendGesture(\n gestureName:\n | \"single_tap\"\n | \"tap_start\"\n | \"double_tap\"\n | \"tap_end\"\n | \"tap_then_hold\"\n | \"touch_down\"\n | \"swipe_up\"\n | \"swipe_down\",\n): void {\n const model = useGlassesStore.getState().deviceModel\n dispatchTouchEvent({\n type: \"touch_event\",\n gestureName,\n deviceModel: Object.values(DeviceModels).find((candidate) => candidate === model) ?? DeviceModels.Simulated,\n timestamp: Date.now(),\n })\n}\n"]}
@@ -16,14 +16,8 @@ declare class HeadingService {
16
16
  private nativeSub;
17
17
  private lastDegrees;
18
18
  private nativeStarted;
19
- /** While true, an external source (glasses magnetometer) owns the stream and phone-compass ticks are dropped. */
20
- private externalSourceActive;
21
19
  private constructor();
22
20
  static getInstance(): HeadingService;
23
- /** While active, phone compass updates are suppressed in favor of pushExternalHeading(). */
24
- setExternalSourceActive(active: boolean): void;
25
- /** Fan an external heading (degrees 0…359) out to listeners; no-op unless the external source is active. */
26
- pushExternalHeading(degrees: number): void;
27
21
  addListener(listener: HeadingListener): () => void;
28
22
  private startNative;
29
23
  private stopNative;
@@ -1 +1 @@
1
- {"version":3,"file":"HeadingService.d.ts","sourceRoot":"","sources":["../../src/services/HeadingService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAEvD,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,aAAa,CAAQ;IAC7B,iHAAiH;IACjH,OAAO,CAAC,oBAAoB,CAAQ;IAEpC,OAAO;WAEO,WAAW,IAAI,cAAc;IAO3C,4FAA4F;IACrF,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAMrD,4GAA4G;IACrG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAa1C,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;YAoB3C,WAAW;YA4BX,UAAU;CAazB;AAED,QAAA,MAAM,cAAc,gBAA+B,CAAA;AACnD,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"HeadingService.d.ts","sourceRoot":"","sources":["../../src/services/HeadingService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;AAEvD,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA8B;IACrD,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,aAAa,CAAQ;IAE7B,OAAO;WAEO,WAAW,IAAI,cAAc;IAOpC,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;YAoB3C,WAAW;YA2BX,UAAU;CAazB;AAED,QAAA,MAAM,cAAc,gBAA+B,CAAA;AACnD,eAAe,cAAc,CAAA"}
@@ -17,8 +17,6 @@ class HeadingService {
17
17
  nativeSub = null;
18
18
  lastDegrees = null;
19
19
  nativeStarted = false;
20
- /** While true, an external source (glasses magnetometer) owns the stream and phone-compass ticks are dropped. */
21
- externalSourceActive = false;
22
20
  constructor() { }
23
21
  static getInstance() {
24
22
  if (!HeadingService.instance) {
@@ -26,29 +24,6 @@ class HeadingService {
26
24
  }
27
25
  return HeadingService.instance;
28
26
  }
29
- /** While active, phone compass updates are suppressed in favor of pushExternalHeading(). */
30
- setExternalSourceActive(active) {
31
- if (this.externalSourceActive === active)
32
- return;
33
- this.externalSourceActive = active;
34
- console.log(`${LOG_TAG}: external heading source ${active ? "active" : "inactive"}`);
35
- }
36
- /** Fan an external heading (degrees 0…359) out to listeners; no-op unless the external source is active. */
37
- pushExternalHeading(degrees) {
38
- if (!this.externalSourceActive)
39
- return;
40
- if (!Number.isFinite(degrees))
41
- return;
42
- this.lastDegrees = degrees;
43
- this.listeners.forEach((l) => {
44
- try {
45
- l(degrees);
46
- }
47
- catch (err) {
48
- console.error(`${LOG_TAG}: listener threw`, err);
49
- }
50
- });
51
- }
52
27
  addListener(listener) {
53
28
  this.listeners.add(listener);
54
29
  if (!this.nativeStarted) {
@@ -74,8 +49,6 @@ class HeadingService {
74
49
  return;
75
50
  this.nativeStarted = true;
76
51
  this.nativeSub = CrustModule.addListener("onHeading", (data) => {
77
- if (this.externalSourceActive)
78
- return;
79
52
  const deg = Number(data.degrees);
80
53
  if (!Number.isFinite(deg))
81
54
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"HeadingService.js","sourceRoot":"","sources":["../../src/services/HeadingService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HeadingService\n *\n * Thin singleton over the native compass stream exposed by `crust`.\n * Works on both Android and iOS via CLLocationManager (iOS) / SensorManager (Android).\n *\n * Reference-counted: the underlying SensorManager subscription starts on\n * the first listener and stops when the last one unsubscribes. Late\n * subscribers get the most recently emitted heading replayed\n * synchronously so the UI doesn't have to wait for the next sensor tick.\n */\n\nimport CrustModule from \"@glassly/crust\"\n\nconst LOG_TAG = \"HEADING_SERVICE\"\n\nexport type HeadingListener = (degrees: number) => void\n\nclass HeadingService {\n private static instance: HeadingService | null = null\n private listeners = new Set<HeadingListener>()\n private nativeSub: {remove: () => void} | null = null\n private lastDegrees: number | null = null\n private nativeStarted = false\n /** While true, an external source (glasses magnetometer) owns the stream and phone-compass ticks are dropped. */\n private externalSourceActive = false\n\n private constructor() {}\n\n public static getInstance(): HeadingService {\n if (!HeadingService.instance) {\n HeadingService.instance = new HeadingService()\n }\n return HeadingService.instance\n }\n\n /** While active, phone compass updates are suppressed in favor of pushExternalHeading(). */\n public setExternalSourceActive(active: boolean): void {\n if (this.externalSourceActive === active) return\n this.externalSourceActive = active\n console.log(`${LOG_TAG}: external heading source ${active ? \"active\" : \"inactive\"}`)\n }\n\n /** Fan an external heading (degrees 0…359) out to listeners; no-op unless the external source is active. */\n public pushExternalHeading(degrees: number): void {\n if (!this.externalSourceActive) return\n if (!Number.isFinite(degrees)) return\n this.lastDegrees = degrees\n this.listeners.forEach((l) => {\n try {\n l(degrees)\n } catch (err) {\n console.error(`${LOG_TAG}: listener threw`, err)\n }\n })\n }\n\n public addListener(listener: HeadingListener): () => void {\n this.listeners.add(listener)\n if (!this.nativeStarted) {\n this.startNative()\n }\n if (this.lastDegrees != null) {\n try {\n listener(this.lastDegrees)\n } catch (err) {\n console.error(`${LOG_TAG}: listener threw on replay`, err)\n }\n }\n return () => {\n this.listeners.delete(listener)\n if (this.listeners.size === 0) {\n this.stopNative()\n }\n }\n }\n\n private async startNative(): Promise<void> {\n if (this.nativeStarted) return\n this.nativeStarted = true\n this.nativeSub = CrustModule.addListener(\"onHeading\", (data) => {\n if (this.externalSourceActive) return\n const deg = Number(data.degrees)\n if (!Number.isFinite(deg)) return\n this.lastDegrees = deg\n this.listeners.forEach((l) => {\n try {\n l(deg)\n } catch (err) {\n console.error(`${LOG_TAG}: listener threw`, err)\n }\n })\n })\n try {\n const result = await CrustModule.startHeading()\n if (!result.ok) {\n console.warn(`${LOG_TAG}: startHeading failed — ${result.error}`)\n } else {\n console.log(`${LOG_TAG}: started`)\n }\n } catch (err) {\n console.error(`${LOG_TAG}: startHeading threw`, err)\n }\n }\n\n private async stopNative(): Promise<void> {\n if (!this.nativeStarted) return\n this.nativeStarted = false\n this.nativeSub?.remove()\n this.nativeSub = null\n this.lastDegrees = null\n try {\n await CrustModule.stopHeading()\n console.log(`${LOG_TAG}: stopped`)\n } catch (err) {\n console.error(`${LOG_TAG}: stopHeading threw`, err)\n }\n }\n}\n\nconst headingService = HeadingService.getInstance()\nexport default headingService\n"]}
1
+ {"version":3,"file":"HeadingService.js","sourceRoot":"","sources":["../../src/services/HeadingService.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HeadingService\n *\n * Thin singleton over the native compass stream exposed by `crust`.\n * Works on both Android and iOS via CLLocationManager (iOS) / SensorManager (Android).\n *\n * Reference-counted: the underlying SensorManager subscription starts on\n * the first listener and stops when the last one unsubscribes. Late\n * subscribers get the most recently emitted heading replayed\n * synchronously so the UI doesn't have to wait for the next sensor tick.\n */\n\nimport CrustModule from \"@glassly/crust\"\n\nconst LOG_TAG = \"HEADING_SERVICE\"\n\nexport type HeadingListener = (degrees: number) => void\n\nclass HeadingService {\n private static instance: HeadingService | null = null\n private listeners = new Set<HeadingListener>()\n private nativeSub: {remove: () => void} | null = null\n private lastDegrees: number | null = null\n private nativeStarted = false\n\n private constructor() {}\n\n public static getInstance(): HeadingService {\n if (!HeadingService.instance) {\n HeadingService.instance = new HeadingService()\n }\n return HeadingService.instance\n }\n\n public addListener(listener: HeadingListener): () => void {\n this.listeners.add(listener)\n if (!this.nativeStarted) {\n this.startNative()\n }\n if (this.lastDegrees != null) {\n try {\n listener(this.lastDegrees)\n } catch (err) {\n console.error(`${LOG_TAG}: listener threw on replay`, err)\n }\n }\n return () => {\n this.listeners.delete(listener)\n if (this.listeners.size === 0) {\n this.stopNative()\n }\n }\n }\n\n private async startNative(): Promise<void> {\n if (this.nativeStarted) return\n this.nativeStarted = true\n this.nativeSub = CrustModule.addListener(\"onHeading\", (data) => {\n const deg = Number(data.degrees)\n if (!Number.isFinite(deg)) return\n this.lastDegrees = deg\n this.listeners.forEach((l) => {\n try {\n l(deg)\n } catch (err) {\n console.error(`${LOG_TAG}: listener threw`, err)\n }\n })\n })\n try {\n const result = await CrustModule.startHeading()\n if (!result.ok) {\n console.warn(`${LOG_TAG}: startHeading failed — ${result.error}`)\n } else {\n console.log(`${LOG_TAG}: started`)\n }\n } catch (err) {\n console.error(`${LOG_TAG}: startHeading threw`, err)\n }\n }\n\n private async stopNative(): Promise<void> {\n if (!this.nativeStarted) return\n this.nativeStarted = false\n this.nativeSub?.remove()\n this.nativeSub = null\n this.lastDegrees = null\n try {\n await CrustModule.stopHeading()\n console.log(`${LOG_TAG}: stopped`)\n } catch (err) {\n console.error(`${LOG_TAG}: stopHeading threw`, err)\n }\n }\n}\n\nconst headingService = HeadingService.getInstance()\nexport default headingService\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"HotspotShutdown.d.ts","sourceRoot":"","sources":["../../src/services/HotspotShutdown.ts"],"names":[],"mappings":"AAAA,KAAK,YAAY,GAAG;IAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;CAAC,CAAA;AAEnD,KAAK,sBAAsB,GAAG;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C,CAAA;AAID;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,EAC5C,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAqBlB"}
1
+ {"version":3,"file":"HotspotShutdown.d.ts","sourceRoot":"","sources":["../../src/services/HotspotShutdown.ts"],"names":[],"mappings":"AAEA,KAAK,YAAY,GAAG;IAAC,KAAK,EAAE,UAAU,GAAG,SAAS,CAAA;CAAC,CAAA;AAEnD,KAAK,sBAAsB,GAAG;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3C,CAAA;AAID;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,EAC5C,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAqBlB"}
@@ -1,4 +1,5 @@
1
- const sleep = (delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs));
1
+ import { BgTimer } from "../utils/timers";
2
+ const sleep = (delayMs) => new Promise((resolve) => BgTimer.setTimeout(resolve, delayMs));
2
3
  /**
3
4
  * Disable a glasses hotspot with a bounded retry. ASG APK replacement keeps the
4
5
  * BLE link alive through BES, but the first command after the new ASG process
@@ -1 +1 @@
1
- {"version":3,"file":"HotspotShutdown.js","sourceRoot":"","sources":["../../src/services/HotspotShutdown.ts"],"names":[],"mappings":"AASA,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;AAE/F;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,eAA4C,EAC5C,UAAkC,EAAE;IAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;IACnD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,IAAI,CAAC,CAAC,CAAA;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAA;IAEnC,IAAI,cAAc,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAA;IAElD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;YACtC,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAA;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,mEAAmE;QACrE,CAAC;QAED,IAAI,OAAO,GAAG,QAAQ,IAAI,YAAY,GAAG,CAAC;YAAE,MAAM,IAAI,CAAC,YAAY,CAAC,CAAA;IACtE,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["type HotspotState = {state: \"disabled\" | \"enabled\"}\n\ntype HotspotShutdownOptions = {\n attempts?: number\n initialDelayMs?: number\n retryDelayMs?: number\n sleep?: (delayMs: number) => Promise<void>\n}\n\nconst sleep = (delayMs: number) => new Promise<void>((resolve) => setTimeout(resolve, delayMs))\n\n/**\n * Disable a glasses hotspot with a bounded retry. ASG APK replacement keeps the\n * BLE link alive through BES, but the first command after the new ASG process\n * appears can still land while its command path is settling.\n */\nexport async function disableHotspotWithRetry(\n requestDisabled: () => Promise<HotspotState>,\n options: HotspotShutdownOptions = {},\n): Promise<boolean> {\n const attempts = Math.max(1, options.attempts ?? 2)\n const initialDelayMs = Math.max(0, options.initialDelayMs ?? 0)\n const retryDelayMs = Math.max(0, options.retryDelayMs ?? 500)\n const wait = options.sleep ?? sleep\n\n if (initialDelayMs > 0) await wait(initialDelayMs)\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n try {\n const status = await requestDisabled()\n if (status.state === \"disabled\") return true\n } catch {\n // A lost command is indistinguishable from a response timeout here. Retry\n // while the phone still owns the hotspot network and local server.\n }\n\n if (attempt < attempts && retryDelayMs > 0) await wait(retryDelayMs)\n }\n\n return false\n}\n"]}
1
+ {"version":3,"file":"HotspotShutdown.js","sourceRoot":"","sources":["../../src/services/HotspotShutdown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAA;AAWvC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;AAEvG;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,eAA4C,EAC5C,UAAkC,EAAE;IAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;IACnD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,cAAc,IAAI,CAAC,CAAC,CAAA;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,IAAI,GAAG,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAA;IAEnC,IAAI,cAAc,GAAG,CAAC;QAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAA;IAElD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;YACtC,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAA;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,mEAAmE;QACrE,CAAC;QAED,IAAI,OAAO,GAAG,QAAQ,IAAI,YAAY,GAAG,CAAC;YAAE,MAAM,IAAI,CAAC,YAAY,CAAC,CAAA;IACtE,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import {BgTimer} from \"../utils/timers\"\n\ntype HotspotState = {state: \"disabled\" | \"enabled\"}\n\ntype HotspotShutdownOptions = {\n attempts?: number\n initialDelayMs?: number\n retryDelayMs?: number\n sleep?: (delayMs: number) => Promise<void>\n}\n\nconst sleep = (delayMs: number) => new Promise<void>((resolve) => BgTimer.setTimeout(resolve, delayMs))\n\n/**\n * Disable a glasses hotspot with a bounded retry. ASG APK replacement keeps the\n * BLE link alive through BES, but the first command after the new ASG process\n * appears can still land while its command path is settling.\n */\nexport async function disableHotspotWithRetry(\n requestDisabled: () => Promise<HotspotState>,\n options: HotspotShutdownOptions = {},\n): Promise<boolean> {\n const attempts = Math.max(1, options.attempts ?? 2)\n const initialDelayMs = Math.max(0, options.initialDelayMs ?? 0)\n const retryDelayMs = Math.max(0, options.retryDelayMs ?? 500)\n const wait = options.sleep ?? sleep\n\n if (initialDelayMs > 0) await wait(initialDelayMs)\n\n for (let attempt = 1; attempt <= attempts; attempt += 1) {\n try {\n const status = await requestDisabled()\n if (status.state === \"disabled\") return true\n } catch {\n // A lost command is indistinguishable from a response timeout here. Retry\n // while the phone still owns the hotspot network and local server.\n }\n\n if (attempt < attempts && retryDelayMs > 0) await wait(retryDelayMs)\n }\n\n return false\n}\n"]}
@@ -14,7 +14,7 @@ export async function submitJSCrashloopReport(params) {
14
14
  trigger: {
15
15
  type: "automatic",
16
16
  source: "miniapp_crashloop",
17
- reason: "glasslyjs_crashloop_disabled",
17
+ reason: "js_crashloop_disabled",
18
18
  sourceAppletPackageName: packageName,
19
19
  sourceAppletName: appName,
20
20
  },
@@ -23,7 +23,7 @@ export async function submitJSCrashloopReport(params) {
23
23
  actualBehavior: JSON.stringify({ reason, lastLogLines }, null, 2),
24
24
  systemPriority: "critical",
25
25
  },
26
- throttleKey: `glasslyjs_crashloop:${packageName}`,
26
+ throttleKey: `js_crashloop:${packageName}`,
27
27
  });
28
28
  const status = toAutomaticReportSubmissionStatus(result);
29
29
  logAutomaticReportSubmissionStatus(LOG_TAG, status, packageName);
@@ -1 +1 @@
1
- {"version":3,"file":"JSCrashloopReportService.js","sourceRoot":"","sources":["../../src/services/JSCrashloopReportService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAA;AAChD,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAElC,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,mBAAmB,EAA0B,MAAM,wBAAwB,CAAA;AAEnF,MAAM,OAAO,GAAG,mBAAmB,CAAA;AAEnC,IAAI,WAAW,GAAwB,IAAI,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAI7C;IACC,MAAM,EAAC,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,EAAE,EAAC,GAAG,MAAM,CAAA;IACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,GAAG,EAAE,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;QACzC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,mBAAmB;YAC3B,MAAM,EAAE,8BAA8B;YACtC,uBAAuB,EAAE,WAAW;YACpC,gBAAgB,EAAE,OAAO;SAC1B;QACD,MAAM,EAAE;YACN,gBAAgB,EAAE,GAAG,OAAO,+BAA+B;YAC3D,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,YAAY,EAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,cAAc,EAAE,UAAU;SAC3B;QACD,WAAW,EAAE,uBAAuB,WAAW,EAAE;KAClD,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACxD,kCAAkC,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;IAChE,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,YAAgC;IAC1D,IAAI,YAAY,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,YAAY,CAAC,WAAW;QAAE,OAAM;IAClF,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAA;IAC5C,MAAM,YAAY,GAAG,gBAAgB,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;IACnF,KAAK,uBAAuB,CAAC;QAC3B,WAAW;QACX,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,YAAY;KACb,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,IAAI,WAAW;QAAE,OAAM;IACvB,WAAW,GAAG,mBAAmB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,WAAW,EAAE,EAAE,CAAA;IACf,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC","sourcesContent":["import {submitAutomaticReport} from \"../facades/reports\"\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {\n logAutomaticReportSubmissionStatus,\n toAutomaticReportSubmissionStatus,\n type AutomaticReportSubmissionStatus,\n} from \"./AutomaticReportResult\"\nimport {getMiniappEngine} from \"./MiniappEngine\"\nimport {islandNotifications, type IslandNotification} from \"./NotificationsEmitter\"\n\nconst LOG_TAG = \"JSCrashloopReport\"\n\nlet unsubscribe: (() => void) | null = null\n\nexport async function submitJSCrashloopReport(params: {\n packageName: string\n reason: string\n lastLogLines?: string[]\n}): Promise<AutomaticReportSubmissionStatus> {\n const {packageName, reason, lastLogLines = []} = params\n const app = useAppStatusStore.getState().apps.find((a) => a.packageName === packageName)\n const appName = app?.name ?? packageName\n const result = await submitAutomaticReport({\n kind: \"automatic\",\n trigger: {\n type: \"automatic\",\n source: \"miniapp_crashloop\",\n reason: \"glasslyjs_crashloop_disabled\",\n sourceAppletPackageName: packageName,\n sourceAppletName: appName,\n },\n report: {\n expectedBehavior: `${appName} should run without crashing.`,\n actualBehavior: JSON.stringify({reason, lastLogLines}, null, 2),\n systemPriority: \"critical\",\n },\n throttleKey: `glasslyjs_crashloop:${packageName}`,\n })\n\n const status = toAutomaticReportSubmissionStatus(result)\n logAutomaticReportSubmissionStatus(LOG_TAG, status, packageName)\n return status\n}\n\nfunction handleNotification(notification: IslandNotification): void {\n if (notification.kind !== \"miniapp_crashloop\" || !notification.packageName) return\n const packageName = notification.packageName\n const lastLogLines = getMiniappEngine()?.router.logRing.snapshot(packageName) ?? []\n void submitJSCrashloopReport({\n packageName,\n reason: notification.reason,\n lastLogLines,\n }).catch((error) => {\n console.error(`[${LOG_TAG}] Unexpected error:`, error)\n })\n}\n\nexport function startJSCrashloopReportService(): void {\n if (unsubscribe) return\n unsubscribe = islandNotifications.subscribe(handleNotification)\n}\n\nexport function stopJSCrashloopReportService(): void {\n unsubscribe?.()\n unsubscribe = null\n}\n"]}
1
+ {"version":3,"file":"JSCrashloopReportService.js","sourceRoot":"","sources":["../../src/services/JSCrashloopReportService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAA;AAChD,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAElC,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,mBAAmB,EAA0B,MAAM,wBAAwB,CAAA;AAEnF,MAAM,OAAO,GAAG,mBAAmB,CAAA;AAEnC,IAAI,WAAW,GAAwB,IAAI,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAI7C;IACC,MAAM,EAAC,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,EAAE,EAAC,GAAG,MAAM,CAAA;IACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,GAAG,EAAE,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;QACzC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,mBAAmB;YAC3B,MAAM,EAAE,uBAAuB;YAC/B,uBAAuB,EAAE,WAAW;YACpC,gBAAgB,EAAE,OAAO;SAC1B;QACD,MAAM,EAAE;YACN,gBAAgB,EAAE,GAAG,OAAO,+BAA+B;YAC3D,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,YAAY,EAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,cAAc,EAAE,UAAU;SAC3B;QACD,WAAW,EAAE,gBAAgB,WAAW,EAAE;KAC3C,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACxD,kCAAkC,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;IAChE,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,YAAgC;IAC1D,IAAI,YAAY,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,YAAY,CAAC,WAAW;QAAE,OAAM;IAClF,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAA;IAC5C,MAAM,YAAY,GAAG,gBAAgB,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;IACnF,KAAK,uBAAuB,CAAC;QAC3B,WAAW;QACX,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,YAAY;KACb,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,IAAI,WAAW;QAAE,OAAM;IACvB,WAAW,GAAG,mBAAmB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,WAAW,EAAE,EAAE,CAAA;IACf,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC","sourcesContent":["import {submitAutomaticReport} from \"../facades/reports\"\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {\n logAutomaticReportSubmissionStatus,\n toAutomaticReportSubmissionStatus,\n type AutomaticReportSubmissionStatus,\n} from \"./AutomaticReportResult\"\nimport {getMiniappEngine} from \"./MiniappEngine\"\nimport {islandNotifications, type IslandNotification} from \"./NotificationsEmitter\"\n\nconst LOG_TAG = \"JSCrashloopReport\"\n\nlet unsubscribe: (() => void) | null = null\n\nexport async function submitJSCrashloopReport(params: {\n packageName: string\n reason: string\n lastLogLines?: string[]\n}): Promise<AutomaticReportSubmissionStatus> {\n const {packageName, reason, lastLogLines = []} = params\n const app = useAppStatusStore.getState().apps.find((a) => a.packageName === packageName)\n const appName = app?.name ?? packageName\n const result = await submitAutomaticReport({\n kind: \"automatic\",\n trigger: {\n type: \"automatic\",\n source: \"miniapp_crashloop\",\n reason: \"js_crashloop_disabled\",\n sourceAppletPackageName: packageName,\n sourceAppletName: appName,\n },\n report: {\n expectedBehavior: `${appName} should run without crashing.`,\n actualBehavior: JSON.stringify({reason, lastLogLines}, null, 2),\n systemPriority: \"critical\",\n },\n throttleKey: `js_crashloop:${packageName}`,\n })\n\n const status = toAutomaticReportSubmissionStatus(result)\n logAutomaticReportSubmissionStatus(LOG_TAG, status, packageName)\n return status\n}\n\nfunction handleNotification(notification: IslandNotification): void {\n if (notification.kind !== \"miniapp_crashloop\" || !notification.packageName) return\n const packageName = notification.packageName\n const lastLogLines = getMiniappEngine()?.router.logRing.snapshot(packageName) ?? []\n void submitJSCrashloopReport({\n packageName,\n reason: notification.reason,\n lastLogLines,\n }).catch((error) => {\n console.error(`[${LOG_TAG}] Unexpected error:`, error)\n })\n}\n\nexport function startJSCrashloopReportService(): void {\n if (unsubscribe) return\n unsubscribe = islandNotifications.subscribe(handleNotification)\n}\n\nexport function stopJSCrashloopReportService(): void {\n unsubscribe?.()\n unsubscribe = null\n}\n"]}
@@ -4,14 +4,14 @@
4
4
  * {@link LocalMiniappRuntime} handler set.
5
5
  *
6
6
  * Rather than re-implement the 33 dispatch arms inline, the router
7
- * consumes Crust's `glasslyjs_message` Expo event and forwards its
7
+ * consumes Crust's `js_message` Expo event and forwards its
8
8
  * `__bridge.send(raw)` payloads to {@link LocalMiniappRuntime.handleRawMessage}.
9
9
  * The SDK envelope shape (`{type: "DISPLAY", ...}` etc.) is unchanged from
10
10
  * the WebView path, so every existing handler runs verbatim. What changes
11
11
  * is the *transport*:
12
12
  *
13
13
  * - **Inbound** (background JS → host): `__dispatch("__bridge", "send",
14
- * [rawJsonString])` → `glasslyjs_message` event → router →
14
+ * [rawJsonString])` → `js_message` event → router →
15
15
  * `LocalMiniappRuntime.handleRawMessage(packageName, raw)`.
16
16
  * - **Outbound** (host → background JS): every package registered with
17
17
  * the router gets a `sendMessage(raw)` fn that calls
@@ -35,6 +35,7 @@
35
35
  */
36
36
  import type { EventSubscription } from "expo-modules-core";
37
37
  import type localMiniappRuntime from "./LocalMiniappRuntime";
38
+ import type { MiniappLaunchSource } from "@glassly/miniapp";
38
39
  import type { InstalledMiniappManifest } from "./LocalMiniappRuntime";
39
40
  import type { JSCrashController } from "./JSCrashController";
40
41
  import { JSLogRingBuffer, JSLogThrottle } from "./JSLogPipeline";
@@ -115,7 +116,7 @@ export declare class JSRouter {
115
116
  uiRouter: UIRouter | null;
116
117
  constructor(runtime: LocalMiniappRuntime, crust: JSCrustBinding, logger?: RouterLogger);
117
118
  /**
118
- * Subscribe to Crust's `glasslyjs_message` event. Idempotent — calling
119
+ * Subscribe to Crust's `js_message` event. Idempotent — calling
119
120
  * start() twice attaches a single listener.
120
121
  */
121
122
  start(): void;
@@ -136,7 +137,7 @@ export declare class JSRouter {
136
137
  * (e.g. {@link spawnAndRegister} below, or the host's miniapp launch
137
138
  * pipeline) should call this once per spawn.
138
139
  */
139
- registerApp(packageName: string, installedManifest?: InstalledMiniappManifest): void;
140
+ registerApp(packageName: string, installedManifest?: InstalledMiniappManifest, launchSource?: MiniappLaunchSource): void;
140
141
  /**
141
142
  * Convenience: spawn a JSContext via Crust, register the app, and
142
143
  * set its declared permissions. Returns true on successful spawn.
@@ -148,6 +149,7 @@ export declare class JSRouter {
148
149
  spawnAndRegister(packageName: string, miniappJs: string, options?: {
149
150
  permissions?: string[];
150
151
  installedManifest?: InstalledMiniappManifest;
152
+ launchSource?: MiniappLaunchSource;
151
153
  }): Promise<boolean>;
152
154
  /**
153
155
  * Crash-controller integration. Called from the `__error` frame
@@ -1 +1 @@
1
- {"version":3,"file":"JSRouter.d.ts","sourceRoot":"","sources":["../../src/services/JSRouter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"JSRouter.d.ts","sourceRoot":"","sources":["../../src/services/JSRouter.ts"],"names":[],"mappings":"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"}
@@ -4,14 +4,14 @@
4
4
  * {@link LocalMiniappRuntime} handler set.
5
5
  *
6
6
  * Rather than re-implement the 33 dispatch arms inline, the router
7
- * consumes Crust's `glasslyjs_message` Expo event and forwards its
7
+ * consumes Crust's `js_message` Expo event and forwards its
8
8
  * `__bridge.send(raw)` payloads to {@link LocalMiniappRuntime.handleRawMessage}.
9
9
  * The SDK envelope shape (`{type: "DISPLAY", ...}` etc.) is unchanged from
10
10
  * the WebView path, so every existing handler runs verbatim. What changes
11
11
  * is the *transport*:
12
12
  *
13
13
  * - **Inbound** (background JS → host): `__dispatch("__bridge", "send",
14
- * [rawJsonString])` → `glasslyjs_message` event → router →
14
+ * [rawJsonString])` → `js_message` event → router →
15
15
  * `LocalMiniappRuntime.handleRawMessage(packageName, raw)`.
16
16
  * - **Outbound** (host → background JS): every package registered with
17
17
  * the router gets a `sendMessage(raw)` fn that calls
@@ -37,6 +37,7 @@ import devServerBridge from "./DevServerBridge";
37
37
  import { JSLogRingBuffer, JSLogThrottle, redactSecrets } from "./JSLogPipeline";
38
38
  import { islandNotifications } from "./NotificationsEmitter";
39
39
  import { miniappRunningRegistry } from "./MiniappRunningRegistry";
40
+ import { BgTimer } from "../utils/timers";
40
41
  const defaultLogger = {
41
42
  log: (m, p) => console.log(`[JSRouter] ${m}`, p ?? ""),
42
43
  warn: (m, p) => console.warn(`[JSRouter] ${m}`, p ?? ""),
@@ -89,13 +90,13 @@ export class JSRouter {
89
90
  this.logger = logger;
90
91
  }
91
92
  /**
92
- * Subscribe to Crust's `glasslyjs_message` event. Idempotent — calling
93
+ * Subscribe to Crust's `js_message` event. Idempotent — calling
93
94
  * start() twice attaches a single listener.
94
95
  */
95
96
  start() {
96
97
  if (this.subscription)
97
98
  return;
98
- this.subscription = this.crust.addListener("glasslyjs_message", (raw) => {
99
+ this.subscription = this.crust.addListener("js_message", (raw) => {
99
100
  try {
100
101
  this.handleOutbound(raw);
101
102
  }
@@ -133,10 +134,10 @@ export class JSRouter {
133
134
  * (e.g. {@link spawnAndRegister} below, or the host's miniapp launch
134
135
  * pipeline) should call this once per spawn.
135
136
  */
136
- registerApp(packageName, installedManifest) {
137
+ registerApp(packageName, installedManifest, launchSource) {
137
138
  this.runtime.registerApp(packageName, (raw) => {
138
139
  this.dispatchBridgeRaw(packageName, raw);
139
- }, installedManifest);
140
+ }, installedManifest, launchSource);
140
141
  this.registered.add(packageName);
141
142
  // JSContext is the source-of-truth for "miniapp running". The
142
143
  // home tile / tray reads this registry to project the `running`
@@ -175,7 +176,7 @@ export class JSRouter {
175
176
  if (options?.permissions && options.permissions.length > 0) {
176
177
  await this.crust.jsSetManifest(packageName, options.permissions);
177
178
  }
178
- this.registerApp(packageName, options?.installedManifest);
179
+ this.registerApp(packageName, options?.installedManifest, options?.launchSource);
179
180
  // Cache spawn arguments so the crash controller can respawn the
180
181
  // same code after a backoff. permissions + manifest are cached too
181
182
  // because the native side resets setManifest on every spawn and
@@ -185,6 +186,7 @@ export class JSRouter {
185
186
  miniappJs,
186
187
  permissions: options?.permissions ?? [],
187
188
  installedManifest: options?.installedManifest,
189
+ launchSource: options?.launchSource,
188
190
  });
189
191
  this.crashController?.onSpawn(packageName);
190
192
  // Fire the `init` envelope so the polyfill's __deliver handler
@@ -231,8 +233,8 @@ export class JSRouter {
231
233
  // Cancel any prior pending respawn before scheduling a new one.
232
234
  const existing = this.respawnTimers.get(packageName);
233
235
  if (existing)
234
- clearTimeout(existing);
235
- const timer = setTimeout(() => {
236
+ BgTimer.clearTimeout(existing);
237
+ const timer = BgTimer.setTimeout(() => {
236
238
  this.respawnTimers.delete(packageName);
237
239
  void (async () => {
238
240
  try {
@@ -249,7 +251,7 @@ export class JSRouter {
249
251
  if (cached.permissions.length > 0) {
250
252
  await this.crust.jsSetManifest(packageName, cached.permissions);
251
253
  }
252
- this.registerApp(packageName, cached.installedManifest);
254
+ this.registerApp(packageName, cached.installedManifest, cached.launchSource);
253
255
  controller.onSpawn(packageName);
254
256
  // Re-fire the init envelope so the respawned context's
255
257
  // `registerMiniapp` handler runs again.
@@ -278,7 +280,7 @@ export class JSRouter {
278
280
  // want a stale timer to re-spawn a miniapp the user just disabled.
279
281
  const pending = this.respawnTimers.get(packageName);
280
282
  if (pending) {
281
- clearTimeout(pending);
283
+ BgTimer.clearTimeout(pending);
282
284
  this.respawnTimers.delete(packageName);
283
285
  }
284
286
  this.spawnCache.delete(packageName);
@@ -319,7 +321,7 @@ export class JSRouter {
319
321
  handleOutbound(msg) {
320
322
  const { packageName, iface, method } = msg;
321
323
  if (!packageName || !iface || !method) {
322
- this.logger.warn(`bad glasslyjs_message — missing fields`, msg);
324
+ this.logger.warn(`bad js_message — missing fields`, msg);
323
325
  return;
324
326
  }
325
327
  // 1) Bridge frames: the SDK's DispatchTransport.send(raw) lands here.
@@ -381,7 +383,7 @@ export class JSRouter {
381
383
  this.logRing.push(packageName, line);
382
384
  // Forward to the `glassly-miniapp dev` sidecar (if one is connected
383
385
  // for this package). Source="background" so the CLI tags lines as
384
- // [GlasslyJS]. The bridge silently drops when no dev server is up,
386
+ // [JSRuntime]. The bridge silently drops when no dev server is up,
385
387
  // which makes this safe to call unconditionally in prod.
386
388
  const argsForBridge = Array.isArray(safeArgs) ? safeArgs : [safeArgs];
387
389
  devServerBridge.forwardLog(packageName, method, argsForBridge, Date.now(), "background");