@mentra/miniapp 0.3.0-dev.0

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 (277) hide show
  1. package/README.md +259 -0
  2. package/dist/background/index.d.ts +59 -0
  3. package/dist/background/index.d.ts.map +1 -0
  4. package/dist/background/index.js +25 -0
  5. package/dist/background/index.js.map +1 -0
  6. package/dist/background/register.d.ts +38 -0
  7. package/dist/background/register.d.ts.map +1 -0
  8. package/dist/background/register.js +75 -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 +62 -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/index.d.ts +58 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +31 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/modules/actions.d.ts +54 -0
  27. package/dist/modules/actions.d.ts.map +1 -0
  28. package/dist/modules/actions.js +122 -0
  29. package/dist/modules/actions.js.map +1 -0
  30. package/dist/modules/auth.d.ts +25 -0
  31. package/dist/modules/auth.d.ts.map +1 -0
  32. package/dist/modules/auth.js +52 -0
  33. package/dist/modules/auth.js.map +1 -0
  34. package/dist/modules/base64.d.ts +16 -0
  35. package/dist/modules/base64.d.ts.map +1 -0
  36. package/dist/modules/base64.js +92 -0
  37. package/dist/modules/base64.js.map +1 -0
  38. package/dist/modules/blob.d.ts +161 -0
  39. package/dist/modules/blob.d.ts.map +1 -0
  40. package/dist/modules/blob.js +277 -0
  41. package/dist/modules/blob.js.map +1 -0
  42. package/dist/modules/camera.d.ts +137 -0
  43. package/dist/modules/camera.d.ts.map +1 -0
  44. package/dist/modules/camera.js +104 -0
  45. package/dist/modules/camera.js.map +1 -0
  46. package/dist/modules/cloud.d.ts +34 -0
  47. package/dist/modules/cloud.d.ts.map +1 -0
  48. package/dist/modules/cloud.js +70 -0
  49. package/dist/modules/cloud.js.map +1 -0
  50. package/dist/modules/dashboard.d.ts +16 -0
  51. package/dist/modules/dashboard.d.ts.map +1 -0
  52. package/dist/modules/dashboard.js +27 -0
  53. package/dist/modules/dashboard.js.map +1 -0
  54. package/dist/modules/display.d.ts +106 -0
  55. package/dist/modules/display.d.ts.map +1 -0
  56. package/dist/modules/display.js +57 -0
  57. package/dist/modules/display.js.map +1 -0
  58. package/dist/modules/events.d.ts +167 -0
  59. package/dist/modules/events.d.ts.map +1 -0
  60. package/dist/modules/events.js +123 -0
  61. package/dist/modules/events.js.map +1 -0
  62. package/dist/modules/glasses.d.ts +28 -0
  63. package/dist/modules/glasses.d.ts.map +1 -0
  64. package/dist/modules/glasses.js +39 -0
  65. package/dist/modules/glasses.js.map +1 -0
  66. package/dist/modules/heading.d.ts +16 -0
  67. package/dist/modules/heading.d.ts.map +1 -0
  68. package/dist/modules/heading.js +20 -0
  69. package/dist/modules/heading.js.map +1 -0
  70. package/dist/modules/imu.d.ts +31 -0
  71. package/dist/modules/imu.d.ts.map +1 -0
  72. package/dist/modules/imu.js +40 -0
  73. package/dist/modules/imu.js.map +1 -0
  74. package/dist/modules/input.d.ts +34 -0
  75. package/dist/modules/input.d.ts.map +1 -0
  76. package/dist/modules/input.js +50 -0
  77. package/dist/modules/input.js.map +1 -0
  78. package/dist/modules/led.d.ts +35 -0
  79. package/dist/modules/led.d.ts.map +1 -0
  80. package/dist/modules/led.js +39 -0
  81. package/dist/modules/led.js.map +1 -0
  82. package/dist/modules/location.d.ts +27 -0
  83. package/dist/modules/location.d.ts.map +1 -0
  84. package/dist/modules/location.js +35 -0
  85. package/dist/modules/location.js.map +1 -0
  86. package/dist/modules/mic.d.ts +44 -0
  87. package/dist/modules/mic.d.ts.map +1 -0
  88. package/dist/modules/mic.js +67 -0
  89. package/dist/modules/mic.js.map +1 -0
  90. package/dist/modules/miniapps.d.ts +72 -0
  91. package/dist/modules/miniapps.d.ts.map +1 -0
  92. package/dist/modules/miniapps.js +48 -0
  93. package/dist/modules/miniapps.js.map +1 -0
  94. package/dist/modules/navigation.d.ts +326 -0
  95. package/dist/modules/navigation.d.ts.map +1 -0
  96. package/dist/modules/navigation.js +386 -0
  97. package/dist/modules/navigation.js.map +1 -0
  98. package/dist/modules/permissions.d.ts +58 -0
  99. package/dist/modules/permissions.d.ts.map +1 -0
  100. package/dist/modules/permissions.js +66 -0
  101. package/dist/modules/permissions.js.map +1 -0
  102. package/dist/modules/phone.d.ts +61 -0
  103. package/dist/modules/phone.d.ts.map +1 -0
  104. package/dist/modules/phone.js +94 -0
  105. package/dist/modules/phone.js.map +1 -0
  106. package/dist/modules/pivots/engine.d.ts +169 -0
  107. package/dist/modules/pivots/engine.d.ts.map +1 -0
  108. package/dist/modules/pivots/engine.js +779 -0
  109. package/dist/modules/pivots/engine.js.map +1 -0
  110. package/dist/modules/pivots/geometry.d.ts +84 -0
  111. package/dist/modules/pivots/geometry.d.ts.map +1 -0
  112. package/dist/modules/pivots/geometry.js +371 -0
  113. package/dist/modules/pivots/geometry.js.map +1 -0
  114. package/dist/modules/pivots/instructions.d.ts +139 -0
  115. package/dist/modules/pivots/instructions.d.ts.map +1 -0
  116. package/dist/modules/pivots/instructions.js +280 -0
  117. package/dist/modules/pivots/instructions.js.map +1 -0
  118. package/dist/modules/speaker.d.ts +163 -0
  119. package/dist/modules/speaker.d.ts.map +1 -0
  120. package/dist/modules/speaker.js +250 -0
  121. package/dist/modules/speaker.js.map +1 -0
  122. package/dist/modules/storage.d.ts +50 -0
  123. package/dist/modules/storage.d.ts.map +1 -0
  124. package/dist/modules/storage.js +99 -0
  125. package/dist/modules/storage.js.map +1 -0
  126. package/dist/modules/stream.d.ts +129 -0
  127. package/dist/modules/stream.d.ts.map +1 -0
  128. package/dist/modules/stream.js +52 -0
  129. package/dist/modules/stream.js.map +1 -0
  130. package/dist/modules/system.d.ts +45 -0
  131. package/dist/modules/system.d.ts.map +1 -0
  132. package/dist/modules/system.js +42 -0
  133. package/dist/modules/system.js.map +1 -0
  134. package/dist/modules/transcription.d.ts +67 -0
  135. package/dist/modules/transcription.d.ts.map +1 -0
  136. package/dist/modules/transcription.js +106 -0
  137. package/dist/modules/transcription.js.map +1 -0
  138. package/dist/modules/translation.d.ts +59 -0
  139. package/dist/modules/translation.d.ts.map +1 -0
  140. package/dist/modules/translation.js +119 -0
  141. package/dist/modules/translation.js.map +1 -0
  142. package/dist/modules/ui.d.ts +186 -0
  143. package/dist/modules/ui.d.ts.map +1 -0
  144. package/dist/modules/ui.js +293 -0
  145. package/dist/modules/ui.js.map +1 -0
  146. package/dist/protocol.d.ts +294 -0
  147. package/dist/protocol.d.ts.map +1 -0
  148. package/dist/protocol.js +320 -0
  149. package/dist/protocol.js.map +1 -0
  150. package/dist/react/MentraProvider.d.ts +33 -0
  151. package/dist/react/MentraProvider.d.ts.map +1 -0
  152. package/dist/react/MentraProvider.js +15 -0
  153. package/dist/react/MentraProvider.js.map +1 -0
  154. package/dist/react/MiniappHeader.d.ts +44 -0
  155. package/dist/react/MiniappHeader.d.ts.map +1 -0
  156. package/dist/react/MiniappHeader.js +32 -0
  157. package/dist/react/MiniappHeader.js.map +1 -0
  158. package/dist/react/index.d.ts +13 -0
  159. package/dist/react/index.d.ts.map +1 -0
  160. package/dist/react/index.js +9 -0
  161. package/dist/react/index.js.map +1 -0
  162. package/dist/react/useCapabilities.d.ts +26 -0
  163. package/dist/react/useCapabilities.d.ts.map +1 -0
  164. package/dist/react/useCapabilities.js +27 -0
  165. package/dist/react/useCapabilities.js.map +1 -0
  166. package/dist/react/useCapsuleHeaderStyle.d.ts +27 -0
  167. package/dist/react/useCapsuleHeaderStyle.d.ts.map +1 -0
  168. package/dist/react/useCapsuleHeaderStyle.js +36 -0
  169. package/dist/react/useCapsuleHeaderStyle.js.map +1 -0
  170. package/dist/react/useColorScheme.d.ts +18 -0
  171. package/dist/react/useColorScheme.d.ts.map +1 -0
  172. package/dist/react/useColorScheme.js +24 -0
  173. package/dist/react/useColorScheme.js.map +1 -0
  174. package/dist/react/useConnected.d.ts +17 -0
  175. package/dist/react/useConnected.d.ts.map +1 -0
  176. package/dist/react/useConnected.js +39 -0
  177. package/dist/react/useConnected.js.map +1 -0
  178. package/dist/react/useRpc.d.ts +29 -0
  179. package/dist/react/useRpc.d.ts.map +1 -0
  180. package/dist/react/useRpc.js +82 -0
  181. package/dist/react/useRpc.js.map +1 -0
  182. package/dist/react/useSafeArea.d.ts +21 -0
  183. package/dist/react/useSafeArea.d.ts.map +1 -0
  184. package/dist/react/useSafeArea.js +22 -0
  185. package/dist/react/useSafeArea.js.map +1 -0
  186. package/dist/session.d.ts +310 -0
  187. package/dist/session.d.ts.map +1 -0
  188. package/dist/session.js +653 -0
  189. package/dist/session.js.map +1 -0
  190. package/dist/sub-path-types.test-d.d.ts +28 -0
  191. package/dist/sub-path-types.test-d.d.ts.map +1 -0
  192. package/dist/sub-path-types.test-d.js +37 -0
  193. package/dist/sub-path-types.test-d.js.map +1 -0
  194. package/dist/transport/auto.d.ts +35 -0
  195. package/dist/transport/auto.d.ts.map +1 -0
  196. package/dist/transport/auto.js +125 -0
  197. package/dist/transport/auto.js.map +1 -0
  198. package/dist/transport/dispatch.d.ts +43 -0
  199. package/dist/transport/dispatch.d.ts.map +1 -0
  200. package/dist/transport/dispatch.js +91 -0
  201. package/dist/transport/dispatch.js.map +1 -0
  202. package/dist/transport/local-socket.d.ts +28 -0
  203. package/dist/transport/local-socket.d.ts.map +1 -0
  204. package/dist/transport/local-socket.js +80 -0
  205. package/dist/transport/local-socket.js.map +1 -0
  206. package/dist/transport/mock.d.ts +54 -0
  207. package/dist/transport/mock.d.ts.map +1 -0
  208. package/dist/transport/mock.js +205 -0
  209. package/dist/transport/mock.js.map +1 -0
  210. package/dist/transport/postmessage.d.ts +36 -0
  211. package/dist/transport/postmessage.d.ts.map +1 -0
  212. package/dist/transport/postmessage.js +78 -0
  213. package/dist/transport/postmessage.js.map +1 -0
  214. package/dist/transport/types.d.ts +25 -0
  215. package/dist/transport/types.d.ts.map +1 -0
  216. package/dist/transport/types.js +11 -0
  217. package/dist/transport/types.js.map +1 -0
  218. package/dist/ui/index.d.ts +98 -0
  219. package/dist/ui/index.d.ts.map +1 -0
  220. package/dist/ui/index.js +32 -0
  221. package/dist/ui/index.js.map +1 -0
  222. package/package.json +75 -0
  223. package/src/background/index.ts +152 -0
  224. package/src/background/register.ts +85 -0
  225. package/src/dev-reload.ts +60 -0
  226. package/src/envelope.ts +54 -0
  227. package/src/globals.ts +62 -0
  228. package/src/index.ts +171 -0
  229. package/src/modules/actions.ts +156 -0
  230. package/src/modules/auth.ts +68 -0
  231. package/src/modules/base64.ts +87 -0
  232. package/src/modules/blob.ts +341 -0
  233. package/src/modules/camera.ts +196 -0
  234. package/src/modules/cloud.ts +94 -0
  235. package/src/modules/dashboard.ts +31 -0
  236. package/src/modules/display.ts +122 -0
  237. package/src/modules/events.ts +264 -0
  238. package/src/modules/glasses.ts +44 -0
  239. package/src/modules/heading.ts +23 -0
  240. package/src/modules/imu.ts +44 -0
  241. package/src/modules/input.ts +71 -0
  242. package/src/modules/led.ts +61 -0
  243. package/src/modules/location.ts +39 -0
  244. package/src/modules/mic.ts +74 -0
  245. package/src/modules/miniapps.ts +90 -0
  246. package/src/modules/navigation.ts +670 -0
  247. package/src/modules/permissions.ts +84 -0
  248. package/src/modules/phone.ts +120 -0
  249. package/src/modules/pivots/engine.ts +863 -0
  250. package/src/modules/pivots/geometry.ts +409 -0
  251. package/src/modules/pivots/instructions.ts +343 -0
  252. package/src/modules/speaker.ts +328 -0
  253. package/src/modules/storage.ts +109 -0
  254. package/src/modules/stream.ts +163 -0
  255. package/src/modules/system.ts +76 -0
  256. package/src/modules/transcription.ts +128 -0
  257. package/src/modules/translation.ts +149 -0
  258. package/src/modules/ui.ts +498 -0
  259. package/src/protocol.ts +371 -0
  260. package/src/react/MentraProvider.tsx +50 -0
  261. package/src/react/MiniappHeader.tsx +122 -0
  262. package/src/react/index.ts +12 -0
  263. package/src/react/useCapabilities.ts +29 -0
  264. package/src/react/useCapsuleHeaderStyle.ts +54 -0
  265. package/src/react/useColorScheme.ts +26 -0
  266. package/src/react/useConnected.ts +47 -0
  267. package/src/react/useRpc.ts +106 -0
  268. package/src/react/useSafeArea.ts +40 -0
  269. package/src/session.ts +878 -0
  270. package/src/sub-path-types.test-d.ts +49 -0
  271. package/src/transport/auto.ts +143 -0
  272. package/src/transport/dispatch.ts +106 -0
  273. package/src/transport/local-socket.ts +93 -0
  274. package/src/transport/mock.ts +248 -0
  275. package/src/transport/postmessage.ts +95 -0
  276. package/src/transport/types.ts +26 -0
  277. package/src/ui/index.ts +122 -0
@@ -0,0 +1,152 @@
1
+ /**
2
+ * @mentra/miniapp/background — background-side SDK entry point.
3
+ *
4
+ * Imported from a miniapp's `src/background/index.ts` to access the
5
+ * per-miniapp `MiniappSession` and its typed `session.*` module
6
+ * wrappers. This is the **always-running JSContext side** of a two-layer
7
+ * miniapp.
8
+ *
9
+ * What's NOT in this entry point:
10
+ * - `mentra` WebView global (UI-only — import from `@mentra/miniapp/ui`).
11
+ * - `MentraProvider` / React hooks (UI-only).
12
+ * - Any DOM-bound API. The JSContext has no DOM.
13
+ *
14
+ * Importing the wrong sub-path is caught at compile time by the
15
+ * separate type-roots on each `exports` entry.
16
+ */
17
+
18
+ export {MiniappSession, type MiniappSessionOptions} from "../session"
19
+ export {registerMiniapp, type MiniappInitHandler} from "./register"
20
+
21
+ // Event / data type re-exports — these are payload shapes a miniapp's
22
+ // background-side handlers consume from session.transcription.on, etc.
23
+ export type {
24
+ TranscriptionData,
25
+ TranslationData,
26
+ ButtonPressData,
27
+ AudioChunkData,
28
+ VadData,
29
+ BatteryData,
30
+ ConnectionData,
31
+ WifiData,
32
+ HeadPositionData,
33
+ AccelData,
34
+ LocationData,
35
+ PhoneNotificationData,
36
+ NotificationDismissedData,
37
+ CalendarEventData,
38
+ HeadingData,
39
+ TouchData,
40
+ UnsubscribeFn,
41
+ } from "../modules/events"
42
+
43
+ // Public envelope + protocol types so authors can write strongly-typed
44
+ // glue when they need to fall back to session.sendOneShot / sendRequest.
45
+ export {MiniappRequestType, MiniappResponseType, MiniappStreamType, MiniappErrorCode} from "../protocol"
46
+
47
+ // Action handler types — for typing `session.actions.handle(id, fn)` handlers
48
+ // (the registering side lives in the background JSContext). `InvokeOptions` is
49
+ // for system miniapps that call other apps' actions via `session.actions.invoke`.
50
+ export type {ActionContext, ActionHandler, InvokeOptions} from "../modules/actions"
51
+
52
+ // Session module types — useful for typing controller classes or
53
+ // utility helpers that take a session-like dependency.
54
+ export type {DisplayManager} from "../modules/display"
55
+ export type {
56
+ CameraFovPreset,
57
+ CameraFovRequest,
58
+ CameraFovResult,
59
+ CameraModule,
60
+ CameraRoiPosition,
61
+ SetCameraFovOptions,
62
+ } from "../modules/camera"
63
+ export type {
64
+ CloudClientAudioTransport,
65
+ CloudClientConnectionStatus,
66
+ CloudClientStatus,
67
+ CloudModule,
68
+ } from "../modules/cloud"
69
+ export type {DashboardAPI} from "../modules/dashboard"
70
+ export type {GlassesModule} from "../modules/glasses"
71
+ export type {HeadingModule} from "../modules/heading"
72
+ export type {ImuModule} from "../modules/imu"
73
+ export type {InputModule} from "../modules/input"
74
+ export type {LedModule} from "../modules/led"
75
+ export type {LocationModule} from "../modules/location"
76
+ export type {MicModule} from "../modules/mic"
77
+ export type {NavigationModule} from "../modules/navigation"
78
+ export type {PermissionsModule} from "../modules/permissions"
79
+ export type {PhoneModule} from "../modules/phone"
80
+ export type {SimpleStorage} from "../modules/storage"
81
+ export {BlobModule, BlobWriter, BlobReader, BLOB_WRITE_CHUNK_BYTES, BLOB_READ_ALL_MAX_BYTES} from "../modules/blob"
82
+ export type {BlobMeta, BlobSetOptions, BlobSetFromUrlOptions, BlobImportOptions} from "../modules/blob"
83
+ export {bytesToBase64, base64ToBytes} from "../modules/base64"
84
+ export type {SpeakerModule} from "../modules/speaker"
85
+ export type {StreamModule} from "../modules/stream"
86
+ export type {SystemModule} from "../modules/system"
87
+ export type {TranscriptionModule} from "../modules/transcription"
88
+ export type {TranslationModule} from "../modules/translation"
89
+ export type {UIModule, UIChannelHandler, UIUnsubscribe} from "../modules/ui"
90
+ export type {Rpc, IsRpc, RpcReq, RpcRes, RpcRequestOptions, RpcHandlerContext} from "../modules/ui"
91
+ export {MentraRpcError, MentraRpcTimeoutError} from "../modules/ui"
92
+
93
+ // Argument enums + option types — for authors writing controllers that pass
94
+ // these into session.* method calls (or that build typed helpers around them).
95
+ // Intentionally NOT re-exported from `@mentra/miniapp/ui` — the WebView half
96
+ // never touches these directly. UI talks to background via mentra.send with
97
+ // the author's own `Channels` registry; background is where these enums show
98
+ // up as method args.
99
+ export type {LedColor, LedControlOptions} from "../modules/led"
100
+ export type {
101
+ ViewType,
102
+ DisplayBreakMode,
103
+ RenderBox,
104
+ RenderElement,
105
+ RenderOptions,
106
+ RenderRectStyle,
107
+ RenderResult,
108
+ RenderTextStyle,
109
+ } from "../modules/display"
110
+ export type {DashboardMode} from "../modules/dashboard"
111
+ export type {PlayAudioOptions, SpeakOptions, SpeakResult, SpeakerState, SpeakerStateEvent} from "../modules/speaker"
112
+ export type {ShareOptions, ShareResult, DownloadOptions, DownloadResult} from "../modules/system"
113
+ export type {TranscriptionConfig} from "../modules/transcription"
114
+ export type {PermissionErrorEvent} from "../modules/permissions"
115
+ export type {
116
+ AuthUpdatePayload,
117
+ MiniappVisibility,
118
+ PermissionType,
119
+ PermissionRecord,
120
+ GlassesCapabilities,
121
+ ConnectAckPayload,
122
+ MiniappAuthState,
123
+ MiniappRequestError,
124
+ } from "../session"
125
+ export type {AuthFetchOptions, AuthModule} from "../modules/auth"
126
+ export type {MiniappColorScheme} from "../globals"
127
+ // Navigation — exported as a single block since the types reference each other.
128
+ export type {
129
+ LatLng,
130
+ TravelMode,
131
+ ManeuverKind,
132
+ RouteAvoidances,
133
+ NavManeuver,
134
+ NavOffRoute,
135
+ NavRerouting,
136
+ NavArrived,
137
+ NavError,
138
+ NavUpdate,
139
+ NavRoute,
140
+ PivotOptions,
141
+ Pivot,
142
+ PivotEvent,
143
+ NavStep,
144
+ NavigationDev,
145
+ StartNavigationOptions,
146
+ NavState,
147
+ NavPermissionResult,
148
+ ComputeRouteOptions,
149
+ ComputedRouteStep,
150
+ ComputedRoute,
151
+ ComputeRouteResult,
152
+ } from "../modules/navigation"
@@ -0,0 +1,85 @@
1
+ /**
2
+ * registerMiniapp — entry hook for the background JSContext.
3
+ *
4
+ * The MentraJS host loads the polyfill (which installs __dispatch /
5
+ * __deliver / timers / fetch / etc.), then evaluates the miniapp's
6
+ * background bundle. After both scripts have evaluated successfully,
7
+ * the host delivers a single `{kind: "init", sessionId}` envelope.
8
+ * The polyfill turns that into a call to `__mentraInitCallback(sessionId)`.
9
+ *
10
+ * This module wires that callback to:
11
+ * 1. Construct a `MiniappSession` (DispatchTransport picks itself
12
+ * automatically because `__dispatch` is on globalThis).
13
+ * 2. Call the user-supplied handler synchronously so subscriptions
14
+ * are registered before any host events fan out.
15
+ * 3. Call `session.connect()` so the host receives CONNECT and the
16
+ * first CONNECT_ACK populates `userId`, `capabilities`, etc.
17
+ *
18
+ * The handler runs once per spawn. If the host kills + respawns the
19
+ * JSContext (crash recovery, dev reload), the polyfill + bundle are
20
+ * re-evaluated and the handler fires again with a fresh session.
21
+ */
22
+
23
+ import {MiniappSession, type MiniappSessionOptions} from "../session"
24
+
25
+ export type MiniappInitHandler = (session: MiniappSession) => void | Promise<void>
26
+
27
+ interface InitGlobals {
28
+ __mentraInitCallback?: (sessionId: string) => void
29
+ /**
30
+ * Polyfill-injected host bridge for surfacing structured errors to the
31
+ * host's MentraJSRouter (which feeds them into MentraJSCrashController).
32
+ * Optional because tests / pure-Node environments don't have it.
33
+ */
34
+ __hostError?: (payloadJson: string) => void
35
+ }
36
+
37
+ /**
38
+ * Register the miniapp's startup handler. Call once at the top level of
39
+ * `src/background/index.ts`. Top-level side effects are fine, but the
40
+ * vast majority of setup should live inside the handler so it can run
41
+ * with a connected session.
42
+ *
43
+ * @example
44
+ * registerMiniapp((session) => {
45
+ * session.transcription.on((tx) => {
46
+ * session.display.render([{type: "text", id: "tx", box, text: tx.text}])
47
+ * })
48
+ * })
49
+ */
50
+ export function registerMiniapp(handler: MiniappInitHandler, options: MiniappSessionOptions = {}): void {
51
+ const g = globalThis as unknown as InitGlobals
52
+ g.__mentraInitCallback = (_sessionId: string) => {
53
+ const session = new MiniappSession(options)
54
+ // Fire the user handler first so any session.* subscriptions get
55
+ // registered before the CONNECT_ACK fan-out lands.
56
+ try {
57
+ const result = handler(session)
58
+ if (result && typeof (result as Promise<void>).then === "function") {
59
+ ;(result as Promise<void>).catch((err: unknown) => {
60
+ // eslint-disable-next-line no-console
61
+ console.error("[mentra-miniapp] registerMiniapp handler rejected:", err)
62
+ })
63
+ }
64
+ } catch (err) {
65
+ // eslint-disable-next-line no-console
66
+ console.error("[mentra-miniapp] registerMiniapp handler threw:", err)
67
+ }
68
+ session.connect().catch((err: unknown) => {
69
+ // eslint-disable-next-line no-console
70
+ console.error("[mentra-miniapp] session.connect() rejected:", err)
71
+ // Surface to the host's crash controller as a structured uncaught
72
+ // error so the existing backoff + crashloop machinery handles it.
73
+ // Repeated connect failures eventually flip the miniapp to
74
+ // CRASHLOOP_DISABLED, which the host turns into a user-facing
75
+ // alert + automatic incident report.
76
+ try {
77
+ const message = err instanceof Error ? err.message : String(err)
78
+ const stack = err instanceof Error && err.stack ? err.stack : ""
79
+ g.__hostError?.(JSON.stringify({message: `session.connect() failed: ${message}`, stack}))
80
+ } catch {
81
+ /* host bridge missing in tests — ignore */
82
+ }
83
+ })
84
+ }
85
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @fileoverview SDK-side dev-reload listener — auto-installed when the host
3
+ * indicates we're running in a dev miniapp.
4
+ *
5
+ * Companion to the phone-side console-tap shim (which is injected by the
6
+ * MentraOS app, not by the SDK). The SDK installs this listener on import so
7
+ * authors get live reload without any opt-in code.
8
+ *
9
+ * Mechanism:
10
+ * - Phone-side `DevServerBridge` receives `{type: "reload"}` from the dev
11
+ * server's WebSocket.
12
+ * - Phone-side `MiniappHost` then injects a `MessageEvent` into the WebView
13
+ * with payload `{type: "miniapp_dev_reload"}`.
14
+ * - This listener catches that MessageEvent and calls `location.reload()`.
15
+ *
16
+ * Gated on `window.MentraOS.miniappDeveloperMode === true` so production
17
+ * miniapps never set up the listener. In production WebViews the host won't
18
+ * inject the message anyway, but belt-and-suspenders.
19
+ */
20
+
21
+ const RELOAD_MESSAGE_TYPE = "miniapp_dev_reload"
22
+
23
+ export function installDevReloadListenerIfDevMode(): void {
24
+ if (typeof window === "undefined") return
25
+ const mentra = (window as {MentraOS?: {miniappDeveloperMode?: boolean}}).MentraOS
26
+ if (!mentra?.miniappDeveloperMode) return
27
+
28
+ // Avoid double-install if the SDK is hot-reloaded mid-session.
29
+ const flagKey = "__mentraDevReloadInstalled"
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ if ((window as any)[flagKey]) return
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ ;(window as any)[flagKey] = true
34
+
35
+ const handler = (ev: MessageEvent): void => {
36
+ const data = typeof ev.data === "string" ? ev.data : null
37
+ if (!data) return
38
+ let parsed: unknown
39
+ try {
40
+ parsed = JSON.parse(data)
41
+ } catch {
42
+ return
43
+ }
44
+ const env = parsed as {payload?: {type?: string}}
45
+ const type = env?.payload?.type
46
+ if (type !== RELOAD_MESSAGE_TYPE) return
47
+ // eslint-disable-next-line no-console
48
+ console.log("[mentra-miniapp] dev reload signal received — reloading")
49
+ try {
50
+ location.reload()
51
+ } catch {
52
+ // Some embedded contexts forbid reload; ignore.
53
+ }
54
+ }
55
+
56
+ window.addEventListener("message", handler)
57
+ if (typeof document !== "undefined") {
58
+ document.addEventListener("message", handler as unknown as EventListener)
59
+ }
60
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @fileoverview Bridge envelope format.
3
+ *
4
+ * Every message between @mentra/miniapp and LocalMiniappRuntime is wrapped in
5
+ * this envelope for request/response correlation.
6
+ *
7
+ * { payload: {...}, requestId?: string }
8
+ */
9
+
10
+ export interface MiniappEnvelope<P = unknown> {
11
+ payload: P
12
+ /** Correlates request/response pairs. Set by the sender when it wants a reply. */
13
+ requestId?: string
14
+ }
15
+
16
+ /** Serialize an envelope for postMessage / WebSocket transport. */
17
+ export function serializeEnvelope(envelope: MiniappEnvelope): string {
18
+ return JSON.stringify(envelope)
19
+ }
20
+
21
+ /**
22
+ * Parse a serialized envelope. Returns null for any malformed input — never throws.
23
+ * Transports should pass raw strings in and silently drop nulls.
24
+ */
25
+ export function parseEnvelope(raw: unknown): MiniappEnvelope | null {
26
+ if (typeof raw !== "string") return null
27
+
28
+ let parsed: unknown
29
+ try {
30
+ parsed = JSON.parse(raw)
31
+ } catch {
32
+ return null
33
+ }
34
+
35
+ if (typeof parsed !== "object" || parsed === null) return null
36
+ const obj = parsed as Record<string, unknown>
37
+
38
+ if (typeof obj.payload !== "object" || obj.payload === null) return null
39
+ if (obj.requestId !== undefined && typeof obj.requestId !== "string") return null
40
+
41
+ return {
42
+ payload: obj.payload as unknown,
43
+ requestId: obj.requestId as string | undefined,
44
+ }
45
+ }
46
+
47
+ /** Generate a short random requestId. Browser-native (crypto.randomUUID). */
48
+ export function makeRequestId(): string {
49
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
50
+ return crypto.randomUUID()
51
+ }
52
+ // Fallback for older engines: timestamp + random suffix. Not cryptographically secure.
53
+ return `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`
54
+ }
package/src/globals.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @fileoverview Shape of window.MentraOS, injected by the host MentraOS app
3
+ * before the miniapp's content loads. Miniapp authors generally won't read
4
+ * this directly — use the typed React hooks (useSafeArea, etc.) instead.
5
+ */
6
+
7
+ export interface MiniappSafeAreaInsets {
8
+ top: number
9
+ bottom: number
10
+ left: number
11
+ right: number
12
+ }
13
+
14
+ export interface MiniappCapsuleMenuRect {
15
+ top: number
16
+ right: number
17
+ bottom: number
18
+ left: number
19
+ width: number
20
+ height: number
21
+ }
22
+
23
+ export type MiniappColorScheme = "light" | "dark"
24
+
25
+ export interface MentraOSGlobals {
26
+ /** Package id the host assigned to this miniapp (e.g. "com.mentra.example"). */
27
+ packageName?: string
28
+ /** "ios" | "android" | other. */
29
+ platform?: string
30
+ /** Capabilities the host exposes to this miniapp (e.g. ["share", "open_url"]). */
31
+ capabilities?: string[]
32
+ /** True when this miniapp is running locally on-device (vs. hosted in the cloud). */
33
+ miniappLocal?: boolean
34
+ /** True when the miniapp is running via the dev workflow (QR sideload). */
35
+ miniappDeveloperMode?: boolean
36
+ /** Safe-area insets around the WebView content. Miniapps should pad accordingly. */
37
+ safeAreaInsets?: MiniappSafeAreaInsets
38
+ /**
39
+ * Bounding rect (in CSS pixels) of the floating capsule menu the host draws
40
+ * over the WebView. The menu lives in the top-right and miniapps should
41
+ * avoid placing interactive elements beneath it.
42
+ */
43
+ capsuleMenu?: MiniappCapsuleMenuRect
44
+ /**
45
+ * The host's current color scheme. Miniapps can follow this to match the
46
+ * phone's appearance. Updates at runtime arrive via the session's
47
+ * `colorScheme` event — see `useColorScheme()` in @mentra/miniapp/react.
48
+ */
49
+ colorScheme?: MiniappColorScheme
50
+ }
51
+
52
+ declare global {
53
+ interface Window {
54
+ MentraOS?: MentraOSGlobals
55
+ }
56
+ }
57
+
58
+ /** Reads window.MentraOS safely — returns an empty object if not set. */
59
+ export function getMentraOSGlobals(): MentraOSGlobals {
60
+ if (typeof window === "undefined") return {}
61
+ return window.MentraOS ?? {}
62
+ }
package/src/index.ts ADDED
@@ -0,0 +1,171 @@
1
+ /**
2
+ * @mentra/miniapp — SDK for building MentraOS local miniapps.
3
+ *
4
+ * Public entry point. Consumers do:
5
+ *
6
+ * import {MiniappSession} from "@mentra/miniapp" // background JSContext
7
+ * import {useColorScheme} from "@mentra/miniapp/react" // UI WebView hooks
8
+ * import {MiniappRequestType} from "@mentra/miniapp/protocol"
9
+ */
10
+
11
+ import {installDevReloadListenerIfDevMode} from "./dev-reload"
12
+
13
+ // Auto-install the dev-reload listener on module import so authors get live
14
+ // reload for free in dev builds. No-op in production (gated on
15
+ // window.MentraOS.miniappDeveloperMode).
16
+ installDevReloadListenerIfDevMode()
17
+
18
+ export {MiniappSession, NotConnectedError} from "./session"
19
+ export type {
20
+ AuthUpdatePayload,
21
+ ConnectAckPayload,
22
+ DisplayCapabilities,
23
+ GlassesCapabilities,
24
+ MiniappAuthState,
25
+ MiniappRequestError,
26
+ MiniappSessionOptions,
27
+ MiniappVisibility,
28
+ } from "./session"
29
+ export type {AuthFetchOptions, AuthModule} from "./modules/auth"
30
+
31
+ export {makeRequestId, parseEnvelope, serializeEnvelope} from "./envelope"
32
+ export type {MiniappEnvelope} from "./envelope"
33
+
34
+ export {getMentraOSGlobals} from "./globals"
35
+ export type {MentraOSGlobals, MiniappCapsuleMenuRect, MiniappColorScheme, MiniappSafeAreaInsets} from "./globals"
36
+
37
+ export {MiniappErrorCode, MiniappRequestType, MiniappResponseType, MiniappStreamType} from "./protocol"
38
+ export {CLOUD_STATUS_STREAM} from "./modules/cloud"
39
+ export type {CloudClientAudioTransport, CloudClientConnectionStatus, CloudClientStatus} from "./modules/cloud"
40
+
41
+ // Hardware requirement types — re-exported from @mentra/types so miniapp
42
+ // authors can type their miniapp.json manifest without pulling in the types
43
+ // package directly. Keep explicit exports (enums as value, interfaces as
44
+ // type) per @mentra/types' Bun-compat convention.
45
+ export {HardwareType, HardwareRequirementLevel} from "@mentra/types"
46
+ export type {HardwareRequirement} from "@mentra/types"
47
+
48
+ // Transports — exported for advanced uses (forced transport injection, tests)
49
+ export {createTransport} from "./transport/auto"
50
+ export type {CreateTransportOptions} from "./transport/auto"
51
+ export {PostMessageTransport} from "./transport/postmessage"
52
+ export {LocalSocketTransport} from "./transport/local-socket"
53
+ export type {LocalSocketTransportOptions} from "./transport/local-socket"
54
+ export {MockTransport, isMockExplicitlyRequested} from "./transport/mock"
55
+ export type {MockTransportOptions} from "./transport/mock"
56
+ export type {Transport, TransportDisconnectHandler, TransportMessageHandler} from "./transport/types"
57
+
58
+ // Module types — useful for typing handlers in consumer code
59
+ export type {
60
+ DisplayBreakMode,
61
+ RenderBox,
62
+ RenderElement,
63
+ RenderOptions,
64
+ RenderRectStyle,
65
+ RenderResult,
66
+ RenderTextStyle,
67
+ ViewType,
68
+ } from "./modules/display"
69
+ export type {
70
+ AccelData,
71
+ AudioChunkData,
72
+ BatteryData,
73
+ ButtonPressData,
74
+ CalendarEventData,
75
+ ConnectionData,
76
+ HeadingData,
77
+ HeadPositionData,
78
+ LocationData,
79
+ NotificationDismissedData,
80
+ PhoneNotificationData,
81
+ TouchData,
82
+ TranscriptionData,
83
+ TranslationData,
84
+ UnsubscribeFn,
85
+ VadData,
86
+ WifiData,
87
+ } from "./modules/events"
88
+ export type {
89
+ PlayAudioOptions,
90
+ SpeakOptions,
91
+ SpeakResult,
92
+ SpeakerState,
93
+ SpeakerStateEvent,
94
+ SpeakerStreamOptions,
95
+ SpeakerStreamSampleRate,
96
+ SpeakerStreamWriteResult,
97
+ } from "./modules/speaker"
98
+ export {SpeakerStreamWriter, SPEAKER_STREAM_MAX_BUFFERED_MS, SPEAKER_WRITE_CHUNK_BYTES} from "./modules/speaker"
99
+ export type {
100
+ CameraFovPreset,
101
+ CameraFovRequest,
102
+ CameraFovResult,
103
+ CameraRoiPosition,
104
+ PhotoTaken,
105
+ SetCameraFovOptions,
106
+ StartVideoRecordingOptions,
107
+ StopVideoRecordingOptions,
108
+ TakePhotoOptions,
109
+ VideoRecordingStarted,
110
+ } from "./modules/camera"
111
+ export type {DashboardMode} from "./modules/dashboard"
112
+ export type {CloudModule} from "./modules/cloud"
113
+ export type {LedColor, LedControlOptions} from "./modules/led"
114
+ export type {
115
+ RestreamDestination,
116
+ StartStreamOptions,
117
+ StreamAudioConfig,
118
+ StreamResolvedConfig,
119
+ StreamResult,
120
+ StreamStatus,
121
+ StreamVideoConfig,
122
+ } from "./modules/stream"
123
+ export type {ShareOptions, ShareResult, DownloadOptions, DownloadResult} from "./modules/system"
124
+ export type {MiniappInfo, MiniappActionInfo, MiniappCompatibility, ListMiniappsOptions} from "./modules/miniapps"
125
+ export type {ActionContext, ActionHandler, InvokeOptions} from "./modules/actions"
126
+
127
+ // Domain module types — exported so consumers can type module references
128
+ // (rare; most authors interact via session.<module>.<method> directly).
129
+ export type {DisplayManager} from "./modules/display"
130
+ export type {MiniappsModule} from "./modules/miniapps"
131
+ export type {ActionsModule} from "./modules/actions"
132
+ export type {GlassesModule} from "./modules/glasses"
133
+ export type {HeadingModule} from "./modules/heading"
134
+ export type {ImuModule} from "./modules/imu"
135
+ export type {InputModule} from "./modules/input"
136
+ export type {LocationModule} from "./modules/location"
137
+ export type {MicModule} from "./modules/mic"
138
+ export type {
139
+ ComputedRoute,
140
+ ComputedRouteStep,
141
+ ComputeRouteOptions,
142
+ ComputeRouteResult,
143
+ LatLng,
144
+ NavArrived,
145
+ NavError,
146
+ NavigationModule,
147
+ NavManeuver,
148
+ NavOffRoute,
149
+ NavPermissionResult,
150
+ NavPlaceDetails,
151
+ NavPlaceSuggestion,
152
+ NavRerouting,
153
+ NavRoute,
154
+ NavState,
155
+ NavStep,
156
+ NavUpdate,
157
+ Pivot,
158
+ PivotEvent,
159
+ PivotOptions,
160
+ RouteAvoidances,
161
+ StartNavigationOptions,
162
+ TravelMode,
163
+ } from "./modules/navigation"
164
+ export type {PermissionsModule, PermissionErrorEvent} from "./modules/permissions"
165
+ export type {PhoneModule, PhoneNotificationsModule, PhoneCalendarModule} from "./modules/phone"
166
+ export type {TranscriptionModule, TranscriptionConfig} from "./modules/transcription"
167
+ export type {TranslationModule} from "./modules/translation"
168
+ export type {SpeakerModule} from "./modules/speaker"
169
+
170
+ // Permission types
171
+ export type {PermissionType, PermissionRecord} from "./session"