@glassly/miniapp 0.1.0-dev.26

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 (312) hide show
  1. package/README.md +275 -0
  2. package/dist/background/index.d.ts +64 -0
  3. package/dist/background/index.d.ts.map +1 -0
  4. package/dist/background/index.js +26 -0
  5. package/dist/background/index.js.map +1 -0
  6. package/dist/background/register.d.ts +39 -0
  7. package/dist/background/register.d.ts.map +1 -0
  8. package/dist/background/register.js +72 -0
  9. package/dist/background/register.js.map +1 -0
  10. package/dist/dev-reload.d.ts +21 -0
  11. package/dist/dev-reload.d.ts.map +1 -0
  12. package/dist/dev-reload.js +60 -0
  13. package/dist/dev-reload.js.map +1 -0
  14. package/dist/envelope.d.ts +23 -0
  15. package/dist/envelope.d.ts.map +1 -0
  16. package/dist/envelope.js +47 -0
  17. package/dist/envelope.js.map +1 -0
  18. package/dist/globals.d.ts +54 -0
  19. package/dist/globals.d.ts.map +1 -0
  20. package/dist/globals.js +12 -0
  21. package/dist/globals.js.map +1 -0
  22. package/dist/hardware.d.ts +24 -0
  23. package/dist/hardware.d.ts.map +1 -0
  24. package/dist/hardware.js +20 -0
  25. package/dist/hardware.js.map +1 -0
  26. package/dist/index.d.ts +65 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +34 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/modules/actions.d.ts +81 -0
  31. package/dist/modules/actions.d.ts.map +1 -0
  32. package/dist/modules/actions.js +137 -0
  33. package/dist/modules/actions.js.map +1 -0
  34. package/dist/modules/ai.d.ts +211 -0
  35. package/dist/modules/ai.d.ts.map +1 -0
  36. package/dist/modules/ai.js +117 -0
  37. package/dist/modules/ai.js.map +1 -0
  38. package/dist/modules/auth.d.ts +25 -0
  39. package/dist/modules/auth.d.ts.map +1 -0
  40. package/dist/modules/auth.js +52 -0
  41. package/dist/modules/auth.js.map +1 -0
  42. package/dist/modules/base64.d.ts +16 -0
  43. package/dist/modules/base64.d.ts.map +1 -0
  44. package/dist/modules/base64.js +92 -0
  45. package/dist/modules/base64.js.map +1 -0
  46. package/dist/modules/blob.d.ts +161 -0
  47. package/dist/modules/blob.d.ts.map +1 -0
  48. package/dist/modules/blob.js +277 -0
  49. package/dist/modules/blob.js.map +1 -0
  50. package/dist/modules/camera.d.ts +183 -0
  51. package/dist/modules/camera.d.ts.map +1 -0
  52. package/dist/modules/camera.js +119 -0
  53. package/dist/modules/camera.js.map +1 -0
  54. package/dist/modules/cloud.d.ts +34 -0
  55. package/dist/modules/cloud.d.ts.map +1 -0
  56. package/dist/modules/cloud.js +70 -0
  57. package/dist/modules/cloud.js.map +1 -0
  58. package/dist/modules/dashboard.d.ts +24 -0
  59. package/dist/modules/dashboard.d.ts.map +1 -0
  60. package/dist/modules/dashboard.js +39 -0
  61. package/dist/modules/dashboard.js.map +1 -0
  62. package/dist/modules/display.d.ts +174 -0
  63. package/dist/modules/display.d.ts.map +1 -0
  64. package/dist/modules/display.js +83 -0
  65. package/dist/modules/display.js.map +1 -0
  66. package/dist/modules/events.d.ts +178 -0
  67. package/dist/modules/events.d.ts.map +1 -0
  68. package/dist/modules/events.js +168 -0
  69. package/dist/modules/events.js.map +1 -0
  70. package/dist/modules/glasses.d.ts +36 -0
  71. package/dist/modules/glasses.d.ts.map +1 -0
  72. package/dist/modules/glasses.js +52 -0
  73. package/dist/modules/glasses.js.map +1 -0
  74. package/dist/modules/heading.d.ts +16 -0
  75. package/dist/modules/heading.d.ts.map +1 -0
  76. package/dist/modules/heading.js +20 -0
  77. package/dist/modules/heading.js.map +1 -0
  78. package/dist/modules/imu.d.ts +31 -0
  79. package/dist/modules/imu.d.ts.map +1 -0
  80. package/dist/modules/imu.js +40 -0
  81. package/dist/modules/imu.js.map +1 -0
  82. package/dist/modules/input.d.ts +50 -0
  83. package/dist/modules/input.d.ts.map +1 -0
  84. package/dist/modules/input.js +70 -0
  85. package/dist/modules/input.js.map +1 -0
  86. package/dist/modules/keys.d.ts +30 -0
  87. package/dist/modules/keys.d.ts.map +1 -0
  88. package/dist/modules/keys.js +37 -0
  89. package/dist/modules/keys.js.map +1 -0
  90. package/dist/modules/languages.d.ts +42 -0
  91. package/dist/modules/languages.d.ts.map +1 -0
  92. package/dist/modules/languages.js +57 -0
  93. package/dist/modules/languages.js.map +1 -0
  94. package/dist/modules/led.d.ts +35 -0
  95. package/dist/modules/led.d.ts.map +1 -0
  96. package/dist/modules/led.js +39 -0
  97. package/dist/modules/led.js.map +1 -0
  98. package/dist/modules/location.d.ts +27 -0
  99. package/dist/modules/location.d.ts.map +1 -0
  100. package/dist/modules/location.js +35 -0
  101. package/dist/modules/location.js.map +1 -0
  102. package/dist/modules/memory.d.ts +126 -0
  103. package/dist/modules/memory.d.ts.map +1 -0
  104. package/dist/modules/memory.js +141 -0
  105. package/dist/modules/memory.js.map +1 -0
  106. package/dist/modules/mic.d.ts +61 -0
  107. package/dist/modules/mic.d.ts.map +1 -0
  108. package/dist/modules/mic.js +94 -0
  109. package/dist/modules/mic.js.map +1 -0
  110. package/dist/modules/miniapps.d.ts +82 -0
  111. package/dist/modules/miniapps.d.ts.map +1 -0
  112. package/dist/modules/miniapps.js +58 -0
  113. package/dist/modules/miniapps.js.map +1 -0
  114. package/dist/modules/navigation.d.ts +332 -0
  115. package/dist/modules/navigation.d.ts.map +1 -0
  116. package/dist/modules/navigation.js +387 -0
  117. package/dist/modules/navigation.js.map +1 -0
  118. package/dist/modules/permissions.d.ts +58 -0
  119. package/dist/modules/permissions.d.ts.map +1 -0
  120. package/dist/modules/permissions.js +66 -0
  121. package/dist/modules/permissions.js.map +1 -0
  122. package/dist/modules/phone.d.ts +95 -0
  123. package/dist/modules/phone.d.ts.map +1 -0
  124. package/dist/modules/phone.js +110 -0
  125. package/dist/modules/phone.js.map +1 -0
  126. package/dist/modules/pivots/engine.d.ts +169 -0
  127. package/dist/modules/pivots/engine.d.ts.map +1 -0
  128. package/dist/modules/pivots/engine.js +778 -0
  129. package/dist/modules/pivots/engine.js.map +1 -0
  130. package/dist/modules/pivots/geometry.d.ts +84 -0
  131. package/dist/modules/pivots/geometry.d.ts.map +1 -0
  132. package/dist/modules/pivots/geometry.js +371 -0
  133. package/dist/modules/pivots/geometry.js.map +1 -0
  134. package/dist/modules/pivots/instructions.d.ts +139 -0
  135. package/dist/modules/pivots/instructions.d.ts.map +1 -0
  136. package/dist/modules/pivots/instructions.js +281 -0
  137. package/dist/modules/pivots/instructions.js.map +1 -0
  138. package/dist/modules/speaker.d.ts +175 -0
  139. package/dist/modules/speaker.d.ts.map +1 -0
  140. package/dist/modules/speaker.js +249 -0
  141. package/dist/modules/speaker.js.map +1 -0
  142. package/dist/modules/speakers.d.ts +29 -0
  143. package/dist/modules/speakers.d.ts.map +1 -0
  144. package/dist/modules/speakers.js +38 -0
  145. package/dist/modules/speakers.js.map +1 -0
  146. package/dist/modules/storage.d.ts +50 -0
  147. package/dist/modules/storage.d.ts.map +1 -0
  148. package/dist/modules/storage.js +99 -0
  149. package/dist/modules/storage.js.map +1 -0
  150. package/dist/modules/stream.d.ts +133 -0
  151. package/dist/modules/stream.d.ts.map +1 -0
  152. package/dist/modules/stream.js +53 -0
  153. package/dist/modules/stream.js.map +1 -0
  154. package/dist/modules/system.d.ts +71 -0
  155. package/dist/modules/system.d.ts.map +1 -0
  156. package/dist/modules/system.js +65 -0
  157. package/dist/modules/system.js.map +1 -0
  158. package/dist/modules/transcription.d.ts +99 -0
  159. package/dist/modules/transcription.d.ts.map +1 -0
  160. package/dist/modules/transcription.js +126 -0
  161. package/dist/modules/transcription.js.map +1 -0
  162. package/dist/modules/translation.d.ts +65 -0
  163. package/dist/modules/translation.d.ts.map +1 -0
  164. package/dist/modules/translation.js +121 -0
  165. package/dist/modules/translation.js.map +1 -0
  166. package/dist/modules/ui.d.ts +186 -0
  167. package/dist/modules/ui.d.ts.map +1 -0
  168. package/dist/modules/ui.js +289 -0
  169. package/dist/modules/ui.js.map +1 -0
  170. package/dist/protocol.d.ts +390 -0
  171. package/dist/protocol.d.ts.map +1 -0
  172. package/dist/protocol.js +419 -0
  173. package/dist/protocol.js.map +1 -0
  174. package/dist/react/MiniappHeader.d.ts +44 -0
  175. package/dist/react/MiniappHeader.d.ts.map +1 -0
  176. package/dist/react/MiniappHeader.js +32 -0
  177. package/dist/react/MiniappHeader.js.map +1 -0
  178. package/dist/react/MiniappProvider.d.ts +33 -0
  179. package/dist/react/MiniappProvider.d.ts.map +1 -0
  180. package/dist/react/MiniappProvider.js +15 -0
  181. package/dist/react/MiniappProvider.js.map +1 -0
  182. package/dist/react/capsuleHeaderLayout.d.ts +3 -0
  183. package/dist/react/capsuleHeaderLayout.d.ts.map +1 -0
  184. package/dist/react/capsuleHeaderLayout.js +5 -0
  185. package/dist/react/capsuleHeaderLayout.js.map +1 -0
  186. package/dist/react/index.d.ts +13 -0
  187. package/dist/react/index.d.ts.map +1 -0
  188. package/dist/react/index.js +9 -0
  189. package/dist/react/index.js.map +1 -0
  190. package/dist/react/useCapabilities.d.ts +26 -0
  191. package/dist/react/useCapabilities.d.ts.map +1 -0
  192. package/dist/react/useCapabilities.js +27 -0
  193. package/dist/react/useCapabilities.js.map +1 -0
  194. package/dist/react/useCapsuleHeaderStyle.d.ts +27 -0
  195. package/dist/react/useCapsuleHeaderStyle.d.ts.map +1 -0
  196. package/dist/react/useCapsuleHeaderStyle.js +39 -0
  197. package/dist/react/useCapsuleHeaderStyle.js.map +1 -0
  198. package/dist/react/useColorScheme.d.ts +18 -0
  199. package/dist/react/useColorScheme.d.ts.map +1 -0
  200. package/dist/react/useColorScheme.js +24 -0
  201. package/dist/react/useColorScheme.js.map +1 -0
  202. package/dist/react/useConnected.d.ts +17 -0
  203. package/dist/react/useConnected.d.ts.map +1 -0
  204. package/dist/react/useConnected.js +39 -0
  205. package/dist/react/useConnected.js.map +1 -0
  206. package/dist/react/useRpc.d.ts +29 -0
  207. package/dist/react/useRpc.d.ts.map +1 -0
  208. package/dist/react/useRpc.js +82 -0
  209. package/dist/react/useRpc.js.map +1 -0
  210. package/dist/react/useSafeArea.d.ts +21 -0
  211. package/dist/react/useSafeArea.d.ts.map +1 -0
  212. package/dist/react/useSafeArea.js +22 -0
  213. package/dist/react/useSafeArea.js.map +1 -0
  214. package/dist/session.d.ts +355 -0
  215. package/dist/session.d.ts.map +1 -0
  216. package/dist/session.js +688 -0
  217. package/dist/session.js.map +1 -0
  218. package/dist/sub-path-types.test-d.d.ts +40 -0
  219. package/dist/sub-path-types.test-d.d.ts.map +1 -0
  220. package/dist/sub-path-types.test-d.js +37 -0
  221. package/dist/sub-path-types.test-d.js.map +1 -0
  222. package/dist/transport/auto.d.ts +35 -0
  223. package/dist/transport/auto.d.ts.map +1 -0
  224. package/dist/transport/auto.js +124 -0
  225. package/dist/transport/auto.js.map +1 -0
  226. package/dist/transport/dispatch.d.ts +43 -0
  227. package/dist/transport/dispatch.d.ts.map +1 -0
  228. package/dist/transport/dispatch.js +91 -0
  229. package/dist/transport/dispatch.js.map +1 -0
  230. package/dist/transport/local-socket.d.ts +28 -0
  231. package/dist/transport/local-socket.d.ts.map +1 -0
  232. package/dist/transport/local-socket.js +80 -0
  233. package/dist/transport/local-socket.js.map +1 -0
  234. package/dist/transport/mock.d.ts +54 -0
  235. package/dist/transport/mock.d.ts.map +1 -0
  236. package/dist/transport/mock.js +210 -0
  237. package/dist/transport/mock.js.map +1 -0
  238. package/dist/transport/postmessage.d.ts +36 -0
  239. package/dist/transport/postmessage.d.ts.map +1 -0
  240. package/dist/transport/postmessage.js +78 -0
  241. package/dist/transport/postmessage.js.map +1 -0
  242. package/dist/transport/types.d.ts +25 -0
  243. package/dist/transport/types.d.ts.map +1 -0
  244. package/dist/transport/types.js +11 -0
  245. package/dist/transport/types.js.map +1 -0
  246. package/dist/ui/index.d.ts +107 -0
  247. package/dist/ui/index.d.ts.map +1 -0
  248. package/dist/ui/index.js +32 -0
  249. package/dist/ui/index.js.map +1 -0
  250. package/package.json +88 -0
  251. package/src/background/index.ts +177 -0
  252. package/src/background/register.ts +89 -0
  253. package/src/dev-reload.ts +59 -0
  254. package/src/envelope.ts +54 -0
  255. package/src/globals.ts +62 -0
  256. package/src/hardware.ts +25 -0
  257. package/src/index.ts +216 -0
  258. package/src/modules/actions.ts +189 -0
  259. package/src/modules/ai.ts +281 -0
  260. package/src/modules/auth.ts +68 -0
  261. package/src/modules/base64.ts +87 -0
  262. package/src/modules/blob.ts +341 -0
  263. package/src/modules/camera.ts +258 -0
  264. package/src/modules/cloud.ts +94 -0
  265. package/src/modules/dashboard.ts +51 -0
  266. package/src/modules/display.ts +214 -0
  267. package/src/modules/events.ts +318 -0
  268. package/src/modules/glasses.ts +58 -0
  269. package/src/modules/heading.ts +23 -0
  270. package/src/modules/imu.ts +44 -0
  271. package/src/modules/input.ts +87 -0
  272. package/src/modules/keys.ts +46 -0
  273. package/src/modules/languages.ts +72 -0
  274. package/src/modules/led.ts +61 -0
  275. package/src/modules/location.ts +39 -0
  276. package/src/modules/memory.ts +224 -0
  277. package/src/modules/mic.ts +103 -0
  278. package/src/modules/miniapps.ts +103 -0
  279. package/src/modules/navigation.ts +674 -0
  280. package/src/modules/permissions.ts +83 -0
  281. package/src/modules/phone.ts +155 -0
  282. package/src/modules/pivots/engine.ts +863 -0
  283. package/src/modules/pivots/geometry.ts +409 -0
  284. package/src/modules/pivots/instructions.ts +341 -0
  285. package/src/modules/speaker.ts +347 -0
  286. package/src/modules/speakers.ts +40 -0
  287. package/src/modules/storage.ts +109 -0
  288. package/src/modules/stream.ts +168 -0
  289. package/src/modules/system.ts +113 -0
  290. package/src/modules/transcription.ts +180 -0
  291. package/src/modules/translation.ts +156 -0
  292. package/src/modules/ui.ts +481 -0
  293. package/src/protocol.ts +482 -0
  294. package/src/react/MiniappHeader.tsx +114 -0
  295. package/src/react/MiniappProvider.tsx +50 -0
  296. package/src/react/capsuleHeaderLayout.ts +11 -0
  297. package/src/react/index.ts +12 -0
  298. package/src/react/useCapabilities.ts +29 -0
  299. package/src/react/useCapsuleHeaderStyle.ts +55 -0
  300. package/src/react/useColorScheme.ts +26 -0
  301. package/src/react/useConnected.ts +47 -0
  302. package/src/react/useRpc.ts +103 -0
  303. package/src/react/useSafeArea.ts +36 -0
  304. package/src/session.ts +969 -0
  305. package/src/sub-path-types.test-d.ts +60 -0
  306. package/src/transport/auto.ts +143 -0
  307. package/src/transport/dispatch.ts +106 -0
  308. package/src/transport/local-socket.ts +91 -0
  309. package/src/transport/mock.ts +255 -0
  310. package/src/transport/postmessage.ts +95 -0
  311. package/src/transport/types.ts +26 -0
  312. package/src/ui/index.ts +129 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * @fileoverview CameraModule — glasses camera control and photo capture.
3
+ */
4
+ import { MiniappRequestType } from "../protocol";
5
+ export class CameraModule {
6
+ constructor(session) {
7
+ this.session = session;
8
+ }
9
+ /** True iff `CAMERA` is declared in the miniapp's manifest. */
10
+ get hasPermission() {
11
+ return this.session._hasManifestPermission("CAMERA");
12
+ }
13
+ /**
14
+ * Apply a session-owned camera FOV/ROI override on the glasses.
15
+ *
16
+ * Resolves after the ASG client reports that the setting was applied to camera
17
+ * hardware after the restart cooldown. The host restores the prior override or persistent base
18
+ * when this miniapp closes. Requires CAMERA permission declared in miniapp.json.
19
+ */
20
+ async setFov(request) {
21
+ return this.session.sendRequest({
22
+ type: MiniappRequestType.CAMERA_FOV,
23
+ ...request,
24
+ });
25
+ }
26
+ /**
27
+ * Take a photo via the glasses camera. Returns a URL to the captured image.
28
+ * Requires CAMERA permission declared in miniapp.json.
29
+ *
30
+ * The photo is uploaded to cloud storage; the returned URL is a short-TTL
31
+ * (~30 minute) signed download URL. If the glasses don't have a camera,
32
+ * the phone-side handler rejects with an error. Check
33
+ * `session.capabilities.hasCamera` before calling.
34
+ */
35
+ async takePhoto(options = {}) {
36
+ return this.session.sendRequest({
37
+ type: MiniappRequestType.PHOTO,
38
+ size: options.size ?? "medium",
39
+ mode: options.mode ?? "photo",
40
+ ...(options.transferMethod !== undefined ? { transferMethod: options.transferMethod } : {}),
41
+ compress: options.compress ?? "none",
42
+ sound: options.sound ?? true,
43
+ saveToGallery: options.saveToGallery ?? false,
44
+ exposureTimeNs: options.exposureTimeNs,
45
+ iso: options.iso,
46
+ aeExposureDivisor: options.aeExposureDivisor,
47
+ isoCap: options.isoCap,
48
+ noiseReduction: options.noiseReduction,
49
+ edgeEnhancement: options.edgeEnhancement,
50
+ zsl: options.zsl,
51
+ mfnr: options.mfnr,
52
+ ispDigitalGain: options.ispDigitalGain,
53
+ ispAnalogGain: options.ispAnalogGain,
54
+ }, options.timeoutMs != null ? { timeoutMs: options.timeoutMs } : undefined);
55
+ }
56
+ /**
57
+ * Pre-warm the glasses camera so the next takePhoto() is near-instant.
58
+ * The camera stays warm for ~durationMs (default 15s, maximum 60s); call warmUp() again to
59
+ * extend it. Warm with the same `size` you'll capture with — a mismatched size
60
+ * forces the camera to reconfigure and loses the speedup. Requires CAMERA
61
+ * permission in miniapp.json. Resolves once the camera reports ready. The host automatically
62
+ * releases this miniapp's request-owned lease when the miniapp closes.
63
+ *
64
+ * Warm-ups are serialized: only one runs at a time and none may start while a
65
+ * photo is being captured. If the camera is busy (a capture is in flight, or
66
+ * another warm-up is still opening) this rejects with `camera_busy` — retry
67
+ * shortly, or just call takePhoto() (it works regardless, only slower). The
68
+ * normal warmUp() → takePhoto() sequence never hits this.
69
+ */
70
+ async warmUp(options = {}) {
71
+ await this.session.sendRequest({
72
+ type: MiniappRequestType.CAMERA_WARM_UP,
73
+ size: options.size ?? "medium",
74
+ mode: options.mode ?? "photo",
75
+ exposureTimeNs: options.exposureTimeNs,
76
+ durationMs: options.durationMs ?? 15000,
77
+ zsl: options.zsl,
78
+ mfnr: options.mfnr,
79
+ });
80
+ }
81
+ /**
82
+ * Start recording video on the glasses camera. Returns a `recordingId` to pass
83
+ * to {@link stopVideoRecording} after the glasses report that recording
84
+ * started. Requires CAMERA permission declared in miniapp.json. Check
85
+ * `session.capabilities.hasCamera` before calling.
86
+ *
87
+ * Resolution and frame rate are optional — omit them to use the device's saved
88
+ * button-video settings. Lowering `fps` (e.g. to 5) keeps the glasses cooler
89
+ * during long recordings.
90
+ */
91
+ async startVideoRecording(options = {}) {
92
+ return this.session.sendRequest({
93
+ type: MiniappRequestType.VIDEO_RECORDING_START,
94
+ width: options.width,
95
+ height: options.height,
96
+ fps: options.fps,
97
+ sound: options.sound ?? true,
98
+ save: options.save ?? false,
99
+ });
100
+ }
101
+ /**
102
+ * Stop an in-progress video recording started with {@link startVideoRecording}.
103
+ *
104
+ * By default the recording stays on the glasses. Pass `uploadUrl` to have the
105
+ * glasses upload the finished clip to your own endpoint.
106
+ *
107
+ * @param recordingId The id returned from `startVideoRecording`.
108
+ * @param options Optional upload destination for the finished recording.
109
+ */
110
+ async stopVideoRecording(recordingId, options = {}) {
111
+ await this.session.sendRequest({
112
+ type: MiniappRequestType.VIDEO_RECORDING_STOP,
113
+ recordingId,
114
+ uploadUrl: options.uploadUrl,
115
+ uploadAuthToken: options.uploadAuthToken,
116
+ });
117
+ }
118
+ }
119
+ //# sourceMappingURL=camera.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera.js","sourceRoot":"","sources":["../../src/modules/camera.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @fileoverview CloudModule — local miniapp view of the phone-owned cloud client.
3
+ *
4
+ * Miniapps do not own or configure the cloud connection. The phone owns one
5
+ * cloud-client instance and pushes status snapshots here so miniapps can render
6
+ * honest UX such as online/offline captions indicators.
7
+ */
8
+ import { MiniappSession } from "../session";
9
+ import type { UnsubscribeFn } from "./events";
10
+ export type CloudClientConnectionStatus = "connected" | "connecting" | "reconnecting" | "disconnected";
11
+ export type CloudClientAudioTransport = "udp" | "ws" | "offline" | "none";
12
+ export interface CloudClientStatus {
13
+ status: CloudClientConnectionStatus;
14
+ audioTransport: CloudClientAudioTransport;
15
+ }
16
+ export declare const CLOUD_STATUS_STREAM = "_cloud_status";
17
+ export declare class CloudModule {
18
+ private readonly session;
19
+ private readonly emitter;
20
+ private current;
21
+ constructor(session: MiniappSession);
22
+ /** Latest status snapshot pushed by the phone runtime. */
23
+ get status(): CloudClientStatus;
24
+ /** True when the phone's cloud-client runtime handshake is complete. */
25
+ get connected(): boolean;
26
+ /** Method alias for callers who prefer function-style state reads. */
27
+ isConnected(): boolean;
28
+ /**
29
+ * Subscribe to cloud-client status updates. The current value is delivered
30
+ * immediately so UI code can hydrate without waiting for the next transition.
31
+ */
32
+ onStatusChanged(handler: (status: CloudClientStatus) => void): UnsubscribeFn;
33
+ }
34
+ //# sourceMappingURL=cloud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.d.ts","sourceRoot":"","sources":["../../src/modules/cloud.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,UAAU,CAAA;AAE3C,MAAM,MAAM,2BAA2B,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc,GAAG,cAAc,CAAA;AACtG,MAAM,MAAM,yBAAyB,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAA;AAEzE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,2BAA2B,CAAA;IACnC,cAAc,EAAE,yBAAyB,CAAA;CAC1C;AAMD,eAAO,MAAM,mBAAmB,kBAAkB,CAAA;AA4BlD,qBAAa,WAAW;IAIV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyC;IACjE,OAAO,CAAC,OAAO,CAAyC;gBAE3B,OAAO,EAAE,cAAc;IAUpD,0DAA0D;IAC1D,IAAI,MAAM,IAAI,iBAAiB,CAE9B;IAED,wEAAwE;IACxE,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,sEAAsE;IACtE,WAAW,IAAI,OAAO;IAItB;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,GAAG,aAAa;CAO7E"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @fileoverview CloudModule — local miniapp view of the phone-owned cloud client.
3
+ *
4
+ * Miniapps do not own or configure the cloud connection. The phone owns one
5
+ * cloud-client instance and pushes status snapshots here so miniapps can render
6
+ * honest UX such as online/offline captions indicators.
7
+ */
8
+ import { EventEmitter } from "eventemitter3";
9
+ export const CLOUD_STATUS_STREAM = "_cloud_status";
10
+ const DEFAULT_STATUS = {
11
+ status: "disconnected",
12
+ audioTransport: "none",
13
+ };
14
+ function normalizeCloudStatus(data) {
15
+ if (!data || typeof data !== "object")
16
+ return null;
17
+ const raw = data;
18
+ const status = raw.status;
19
+ const audioTransport = raw.audioTransport;
20
+ if (status !== "connected" && status !== "connecting" && status !== "reconnecting" && status !== "disconnected") {
21
+ return null;
22
+ }
23
+ if (audioTransport !== "udp" &&
24
+ audioTransport !== "ws" &&
25
+ audioTransport !== "offline" &&
26
+ audioTransport !== "none") {
27
+ return null;
28
+ }
29
+ return { status, audioTransport };
30
+ }
31
+ export class CloudModule {
32
+ constructor(session) {
33
+ this.session = session;
34
+ this.emitter = new EventEmitter();
35
+ this.current = { ...DEFAULT_STATUS };
36
+ this.session._subscribe(CLOUD_STATUS_STREAM, (data) => {
37
+ const next = normalizeCloudStatus(data);
38
+ if (!next)
39
+ return;
40
+ if (next.status === this.current.status && next.audioTransport === this.current.audioTransport)
41
+ return;
42
+ this.current = next;
43
+ this.emitter.emit("status", { ...this.current });
44
+ });
45
+ }
46
+ /** Latest status snapshot pushed by the phone runtime. */
47
+ get status() {
48
+ return { ...this.current };
49
+ }
50
+ /** True when the phone's cloud-client runtime handshake is complete. */
51
+ get connected() {
52
+ return this.current.status === "connected";
53
+ }
54
+ /** Method alias for callers who prefer function-style state reads. */
55
+ isConnected() {
56
+ return this.connected;
57
+ }
58
+ /**
59
+ * Subscribe to cloud-client status updates. The current value is delivered
60
+ * immediately so UI code can hydrate without waiting for the next transition.
61
+ */
62
+ onStatusChanged(handler) {
63
+ handler({ ...this.current });
64
+ this.emitter.on("status", handler);
65
+ return () => {
66
+ this.emitter.off("status", handler);
67
+ };
68
+ }
69
+ }
70
+ //# sourceMappingURL=cloud.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud.js","sourceRoot":"","sources":["../../src/modules/cloud.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAC,YAAY,EAAC,MAAM,eAAe,CAAA;AAiB1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,eAAe,CAAA;AAElD,MAAM,cAAc,GAAsB;IACxC,MAAM,EAAE,cAAc;IACtB,cAAc,EAAE,MAAM;CACvB,CAAA;AAED,SAAS,oBAAoB,CAAC,IAAa;IACzC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IAClD,MAAM,GAAG,GAAG,IAA+B,CAAA;IAC3C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;IACzB,MAAM,cAAc,GAAG,GAAG,CAAC,cAAc,CAAA;IAEzC,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,YAAY,IAAI,MAAM,KAAK,cAAc,IAAI,MAAM,KAAK,cAAc,EAAE,CAAC;QAChH,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IACE,cAAc,KAAK,KAAK;QACxB,cAAc,KAAK,IAAI;QACvB,cAAc,KAAK,SAAS;QAC5B,cAAc,KAAK,MAAM,EACzB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,EAAC,MAAM,EAAE,cAAc,EAAC,CAAA;AACjC,CAAC;AAED,MAAM,OAAO,WAAW;IAItB,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;QAHnC,YAAO,GAAG,IAAI,YAAY,EAAsB,CAAA;QACzD,YAAO,GAAsB,EAAC,GAAG,cAAc,EAAC,CAAA;QAGtD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,EAAE;YACpD,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAA;YACvC,IAAI,CAAC,IAAI;gBAAE,OAAM;YACjB,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC,OAAO,CAAC,cAAc;gBAAE,OAAM;YACtG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;YACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAC,GAAG,IAAI,CAAC,OAAO,EAAC,CAAC,CAAA;QAChD,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,0DAA0D;IAC1D,IAAI,MAAM;QACR,OAAO,EAAC,GAAG,IAAI,CAAC,OAAO,EAAC,CAAA;IAC1B,CAAC;IAED,wEAAwE;IACxE,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,WAAW,CAAA;IAC5C,CAAC;IAED,sEAAsE;IACtE,WAAW;QACT,OAAO,IAAI,CAAC,SAAS,CAAA;IACvB,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,OAA4C;QAC1D,OAAO,CAAC,EAAC,GAAG,IAAI,CAAC,OAAO,EAAC,CAAC,CAAA;QAC1B,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAClC,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QACrC,CAAC,CAAA;IACH,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview DashboardAPI. setContent() is a noop in v1 (the cloud
3
+ * DashboardManager owns widget rendering); showNativeDashboard() is live.
4
+ */
5
+ import { MiniappSession } from "../session";
6
+ export type DashboardMode = "main" | "expanded" | "always_on";
7
+ /** "shown" = forwarded to the glasses; "unsupported" = the host refused (e.g. native nav mode owns the screen). */
8
+ export interface ShowNativeDashboardResult {
9
+ status: "shown" | "unsupported";
10
+ reason?: string;
11
+ }
12
+ export declare class DashboardAPI {
13
+ private readonly session;
14
+ private warned;
15
+ constructor(session: MiniappSession);
16
+ setContent(mode: DashboardMode, content: string): void;
17
+ /**
18
+ * Bring the glasses' native dashboard (the OS-level idle screen) to the
19
+ * foreground. On the G2 this tears down the current page; the display
20
+ * returns when the wearer dismisses the dashboard or content is re-rendered.
21
+ */
22
+ showNativeDashboard(): Promise<ShowNativeDashboardResult>;
23
+ }
24
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/modules/dashboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AAEzC,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,CAAA;AAE7D,mHAAmH;AACnH,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,OAAO,GAAG,aAAa,CAAA;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,MAAM,CAAQ;gBAEO,OAAO,EAAE,cAAc;IAEpD,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAatD;;;;OAIG;IACH,mBAAmB,IAAI,OAAO,CAAC,yBAAyB,CAAC;CAW1D"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview DashboardAPI. setContent() is a noop in v1 (the cloud
3
+ * DashboardManager owns widget rendering); showNativeDashboard() is live.
4
+ */
5
+ import { MiniappRequestType } from "../protocol";
6
+ export class DashboardAPI {
7
+ constructor(session) {
8
+ this.session = session;
9
+ this.warned = false;
10
+ }
11
+ setContent(mode, content) {
12
+ if (!this.warned) {
13
+ console.warn("[@glassly/miniapp] dashboard.setContent() is deferred in v1.");
14
+ this.warned = true;
15
+ }
16
+ // Still forward so the phone can log/ignore consistently.
17
+ this.session.sendOneShot({
18
+ type: MiniappRequestType.DASHBOARD_CONTENT_UPDATE,
19
+ mode,
20
+ content,
21
+ });
22
+ }
23
+ /**
24
+ * Bring the glasses' native dashboard (the OS-level idle screen) to the
25
+ * foreground. On the G2 this tears down the current page; the display
26
+ * returns when the wearer dismisses the dashboard or content is re-rendered.
27
+ */
28
+ showNativeDashboard() {
29
+ return this.session
30
+ .sendRequest({ type: MiniappRequestType.SHOW_NATIVE_DASHBOARD })
31
+ .catch((err) => ({
32
+ status: "unsupported",
33
+ reason: typeof err === "object" && err !== null && "message" in err
34
+ ? String(err.message)
35
+ : String(err),
36
+ }));
37
+ }
38
+ }
39
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/modules/dashboard.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAA;AAW9C,MAAM,OAAO,YAAY;IAGvB,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;QAF5C,WAAM,GAAG,KAAK,CAAA;IAEiC,CAAC;IAExD,UAAU,CAAC,IAAmB,EAAE,OAAe;QAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAA;YAC5E,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QACpB,CAAC;QACD,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;YACvB,IAAI,EAAE,kBAAkB,CAAC,wBAAwB;YACjD,IAAI;YACJ,OAAO;SACR,CAAC,CAAA;IACJ,CAAC;IAED;;;;OAIG;IACH,mBAAmB;QACjB,OAAO,IAAI,CAAC,OAAO;aAChB,WAAW,CAA4B,EAAC,IAAI,EAAE,kBAAkB,CAAC,qBAAqB,EAAC,CAAC;aACxF,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACf,MAAM,EAAE,aAAsB;YAC9B,MAAM,EACJ,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG;gBACzD,CAAC,CAAC,MAAM,CAAE,GAA0B,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC,CAAA;IACP,CAAC;CACF"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * @fileoverview DisplayManager — the glasses display, via `render()`.
3
+ *
4
+ * render(elements) is replace-the-frame scene rendering: each call describes
5
+ * everything that should be on screen, the host diffs it against the previous
6
+ * frame per device, and `render([])` clears. The legacy one-shot `show*`
7
+ * layout methods were removed once nothing first-party or known-external
8
+ * called them; hosts still accept the historical `miniapp_display` wire shape
9
+ * from bundles packed with older SDKs.
10
+ */
11
+ import { MiniappSession } from "../session";
12
+ export type ViewType = "main" | "dashboard";
13
+ export type DisplayBreakMode = "character" | "character-no-hyphen" | "word" | "strict-word";
14
+ /** Canvas corner a box's `x`/`y` are measured from (insets grow inward). */
15
+ export type RenderAnchor = "top-left" | "top-right" | "bottom-left" | "bottom-right";
16
+ /**
17
+ * Pixel-space bounding box on the device's drawable canvas (see
18
+ * `capabilities.display`).
19
+ *
20
+ * With an `anchor`, `x`/`y` become insets from that corner, growing inward,
21
+ * and the host resolves the box against the connected device's real canvas —
22
+ * e.g. `{x: 0, y: 0, w: 120, h: 120, anchor: "bottom-right"}` sits flush in
23
+ * the bottom-right corner on every device, whatever its resolution. Corners
24
+ * only; there is no center/edge anchoring or scaling. Hosts older than the
25
+ * anchor feature ignore the field and place the box from the top-left.
26
+ */
27
+ export interface RenderBox {
28
+ x: number;
29
+ y: number;
30
+ w: number;
31
+ h: number;
32
+ /** Which canvas corner x/y are measured from. Default "top-left". */
33
+ anchor?: RenderAnchor;
34
+ }
35
+ export interface RenderTextStyle {
36
+ /** Border width in px (0/absent = none). */
37
+ border?: number;
38
+ /** Border corner radius in px. */
39
+ radius?: number;
40
+ /** What happens to text that doesn't fit the box after wrapping. Default "clip". */
41
+ overflow?: "clip" | "ellipsis";
42
+ /** Line-break policy for wrapping (host wraps; the box carries pre-wrapped text). */
43
+ breakMode?: DisplayBreakMode;
44
+ /**
45
+ * "mono": fixed-pitch text drawn at `fontSize` px with a fixed line height
46
+ * of 1.2 × size, and NOT re-wrapped by the host — lines are taken as given.
47
+ * For grids (terminals, tables). Devices without a phone-side rasterizer
48
+ * (stock G2 firmware) fall back to their own proportional font.
49
+ *
50
+ * "builtin": the glasses draw the text themselves with their built-in 20 px
51
+ * proportional font (Glassly CFW G2 only — tiny updates instead of bitmap
52
+ * re-sends). Lines are taken as given (split on \n, never re-wrapped) and
53
+ * clipped at the display edge, and the render window is pinned to the
54
+ * middle depth level while such text is on screen. Other devices and stock
55
+ * firmware fall back to the default proportional face.
56
+ */
57
+ font?: "default" | "mono" | "builtin";
58
+ /** Font size in px for `font: "mono"`. Default 20. */
59
+ fontSize?: number;
60
+ }
61
+ export interface RenderRectStyle {
62
+ border?: number;
63
+ radius?: number;
64
+ }
65
+ /**
66
+ * One element of a rendered scene. `id` is optional but recommended for
67
+ * anything that updates over time: elements with a stable id update in place on
68
+ * the glasses (no flicker); the host matches unnamed elements by geometry.
69
+ */
70
+ export type RenderElement = {
71
+ type: "text";
72
+ id?: string;
73
+ box: RenderBox;
74
+ text: string;
75
+ style?: RenderTextStyle;
76
+ } | {
77
+ type: "image";
78
+ id?: string;
79
+ box: RenderBox;
80
+ data: string;
81
+ } | {
82
+ type: "rect";
83
+ id?: string;
84
+ box: RenderBox;
85
+ style?: RenderRectStyle;
86
+ };
87
+ export interface RenderOptions {
88
+ view?: ViewType;
89
+ /** Auto-clear after this many ms (same semantics as legacy display options). */
90
+ durationMs?: number;
91
+ }
92
+ /** Turn-by-turn card fields — pre-formatted display strings, rendered verbatim by the device. */
93
+ export interface NativeNavInfo {
94
+ /** Firmware direction-icon index, 0…35. */
95
+ directionIcon: number;
96
+ /** Distance to the next maneuver, e.g. "500 m". */
97
+ distance: string;
98
+ roadName: string;
99
+ /** Remaining trip duration, e.g. "11 min". */
100
+ spendTime: string;
101
+ /** Distance to the destination, e.g. "0.9 km". */
102
+ remainDistance: string;
103
+ /** Arrival time, e.g. "18:18". */
104
+ etaTime: string;
105
+ /** Current speed, e.g. "5 km/h". */
106
+ speed: string;
107
+ }
108
+ /**
109
+ * "sent" = forwarded to the device. "unsupported" = no native nav UI on this
110
+ * device / no active trip — callers should fall back to render().
111
+ */
112
+ export interface NativeNavResult {
113
+ status: "sent" | "unsupported" | "blocked";
114
+ reason?: string;
115
+ }
116
+ /**
117
+ * Outcome of a render request, resolved when the host's display arbitration
118
+ * settles it. "displayed" = accepted and sent to the device — NOT a
119
+ * render confirmation. "blocked" = another app owns the display (or the
120
+ * request failed); `reason` says why.
121
+ */
122
+ export interface RenderResult {
123
+ status: "displayed" | "blocked";
124
+ /** True when the host adjusted the scene (clamped boxes, dropped elements, degraded for the device). */
125
+ degraded?: boolean;
126
+ /** Ids of elements the host dropped (budget/bounds/device limits) — dropped is never silent. */
127
+ dropped?: string[];
128
+ reason?: string;
129
+ }
130
+ export declare class DisplayManager {
131
+ private readonly session;
132
+ constructor(session: MiniappSession);
133
+ /**
134
+ * Render a whole scene of positioned elements — replace-the-frame.
135
+ *
136
+ * Each call describes everything that should be on screen; the host diffs it
137
+ * against the previous frame per device (elements with a stable `id` update
138
+ * in place; elements you stop sending are removed). There is no lifecycle to
139
+ * manage and no remove calls — `render([])` clears.
140
+ *
141
+ * Coordinates are raw pixels on the device's drawable canvas — read
142
+ * `session.capabilities.display` (populated on the "ready" event) for the
143
+ * real width/height and element budgets. Out-of-bounds boxes are clamped and
144
+ * over-budget elements are dropped tail-first; both are reported via the
145
+ * result, never silently.
146
+ *
147
+ * Awaiting is OPT-IN — a plain fire-and-forget call is fine. The returned
148
+ * promise never rejects.
149
+ *
150
+ * @example
151
+ * const result = await session.display.render([
152
+ * {type: "text", id: "stats", box: {x: 12, y: 9, w: 200, h: 28}, text: "863 m 11 min"},
153
+ * {type: "image", id: "map", box: {x: 335, y: 14, w: 150, h: 150}, data: mapPng},
154
+ * {type: "rect", box: {x: 0, y: 0, w: 500, h: 220}, style: {radius: 4}},
155
+ * ])
156
+ * if (result.degraded) console.warn("dropped:", result.dropped)
157
+ */
158
+ render(elements: RenderElement[], options?: RenderOptions): Promise<RenderResult>;
159
+ /** Update the native nav UI's turn-by-turn card. */
160
+ sendNativeNavInfo(info: NativeNavInfo): Promise<NativeNavResult>;
161
+ /**
162
+ * Push the native nav UI's live mini map (base64 BMP/PNG; the host re-encodes
163
+ * and scales to the device's slot — 176×176 on G2). Draw north-up with the
164
+ * cursor centred; the device rotates the bitmap by `rotationDeg`.
165
+ */
166
+ sendNativeNavMiniMap(data: string, options?: {
167
+ rotationDeg?: number;
168
+ border?: boolean;
169
+ }): Promise<NativeNavResult>;
170
+ /** Push the native nav UI's overview (full-route) map — 576×188 on G2. */
171
+ sendNativeNavOverviewMap(data: string): Promise<NativeNavResult>;
172
+ private sendNativeNav;
173
+ }
174
+ //# sourceMappingURL=display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../src/modules/display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * @fileoverview DisplayManager — the glasses display, via `render()`.
3
+ *
4
+ * render(elements) is replace-the-frame scene rendering: each call describes
5
+ * everything that should be on screen, the host diffs it against the previous
6
+ * frame per device, and `render([])` clears. The legacy one-shot `show*`
7
+ * layout methods were removed once nothing first-party or known-external
8
+ * called them; hosts still accept the historical `miniapp_display` wire shape
9
+ * from bundles packed with older SDKs.
10
+ */
11
+ import { MiniappRequestType } from "../protocol";
12
+ export class DisplayManager {
13
+ constructor(session) {
14
+ this.session = session;
15
+ }
16
+ /**
17
+ * Render a whole scene of positioned elements — replace-the-frame.
18
+ *
19
+ * Each call describes everything that should be on screen; the host diffs it
20
+ * against the previous frame per device (elements with a stable `id` update
21
+ * in place; elements you stop sending are removed). There is no lifecycle to
22
+ * manage and no remove calls — `render([])` clears.
23
+ *
24
+ * Coordinates are raw pixels on the device's drawable canvas — read
25
+ * `session.capabilities.display` (populated on the "ready" event) for the
26
+ * real width/height and element budgets. Out-of-bounds boxes are clamped and
27
+ * over-budget elements are dropped tail-first; both are reported via the
28
+ * result, never silently.
29
+ *
30
+ * Awaiting is OPT-IN — a plain fire-and-forget call is fine. The returned
31
+ * promise never rejects.
32
+ *
33
+ * @example
34
+ * const result = await session.display.render([
35
+ * {type: "text", id: "stats", box: {x: 12, y: 9, w: 200, h: 28}, text: "863 m 11 min"},
36
+ * {type: "image", id: "map", box: {x: 335, y: 14, w: 150, h: 150}, data: mapPng},
37
+ * {type: "rect", box: {x: 0, y: 0, w: 500, h: 220}, style: {radius: 4}},
38
+ * ])
39
+ * if (result.degraded) console.warn("dropped:", result.dropped)
40
+ */
41
+ render(elements, options = {}) {
42
+ return this.session
43
+ .sendRequest({
44
+ type: MiniappRequestType.RENDER,
45
+ view: options.view ?? "main",
46
+ elements,
47
+ durationMs: options.durationMs,
48
+ })
49
+ .catch((err) => ({
50
+ status: "blocked",
51
+ reason: typeof err === "object" && err !== null && "message" in err
52
+ ? String(err.message)
53
+ : String(err),
54
+ }));
55
+ }
56
+ /** Update the native nav UI's turn-by-turn card. */
57
+ sendNativeNavInfo(info) {
58
+ return this.sendNativeNav({ action: "info", info });
59
+ }
60
+ /**
61
+ * Push the native nav UI's live mini map (base64 BMP/PNG; the host re-encodes
62
+ * and scales to the device's slot — 176×176 on G2). Draw north-up with the
63
+ * cursor centred; the device rotates the bitmap by `rotationDeg`.
64
+ */
65
+ sendNativeNavMiniMap(data, options = {}) {
66
+ return this.sendNativeNav({ action: "mini_map", map: { data, ...options } });
67
+ }
68
+ /** Push the native nav UI's overview (full-route) map — 576×188 on G2. */
69
+ sendNativeNavOverviewMap(data) {
70
+ return this.sendNativeNav({ action: "overview_map", map: { data } });
71
+ }
72
+ sendNativeNav(payload) {
73
+ return this.session
74
+ .sendRequest({ type: MiniappRequestType.NATIVE_NAV, ...payload })
75
+ .catch((err) => ({
76
+ status: "unsupported",
77
+ reason: typeof err === "object" && err !== null && "message" in err
78
+ ? String(err.message)
79
+ : String(err),
80
+ }));
81
+ }
82
+ }
83
+ //# sourceMappingURL=display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/modules/display.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAC,kBAAkB,EAAC,MAAM,aAAa,CAAA;AA+H9C,MAAM,OAAO,cAAc;IACzB,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAExD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,MAAM,CAAC,QAAyB,EAAE,UAAyB,EAAE;QAC3D,OAAO,IAAI,CAAC,OAAO;aAChB,WAAW,CAAe;YACzB,IAAI,EAAE,kBAAkB,CAAC,MAAM;YAC/B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,MAAM;YAC5B,QAAQ;YACR,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACf,MAAM,EAAE,SAAkB;YAC1B,MAAM,EACJ,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG;gBACzD,CAAC,CAAC,MAAM,CAAE,GAA0B,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC,CAAA;IACP,CAAC;IAED,oDAAoD;IACpD,iBAAiB,CAAC,IAAmB;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,EAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAC,CAAC,CAAA;IACnD,CAAC;IAED;;;;OAIG;IACH,oBAAoB,CAAC,IAAY,EAAE,UAAoD,EAAE;QACvF,OAAO,IAAI,CAAC,aAAa,CAAC,EAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,EAAC,IAAI,EAAE,GAAG,OAAO,EAAC,EAAC,CAAC,CAAA;IAC1E,CAAC;IAED,0EAA0E;IAC1E,wBAAwB,CAAC,IAAY;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,EAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,EAAC,IAAI,EAAC,EAAC,CAAC,CAAA;IAClE,CAAC;IAEO,aAAa,CAAC,OAAgC;QACpD,OAAO,IAAI,CAAC,OAAO;aAChB,WAAW,CAAkB,EAAC,IAAI,EAAE,kBAAkB,CAAC,UAAU,EAAE,GAAG,OAAO,EAAC,CAAC;aAC/E,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACf,MAAM,EAAE,aAAsB;YAC9B,MAAM,EACJ,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,GAAG;gBACzD,CAAC,CAAC,MAAM,CAAE,GAA0B,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAClB,CAAC,CAAC,CAAA;IACP,CAAC;CACF"}