@mentra/miniapp 0.3.0-beta.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 +60 -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 +59 -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 +170 -0
  43. package/dist/modules/camera.d.ts.map +1 -0
  44. package/dist/modules/camera.js +116 -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 +160 -0
  59. package/dist/modules/events.d.ts.map +1 -0
  60. package/dist/modules/events.js +168 -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 +95 -0
  103. package/dist/modules/phone.d.ts.map +1 -0
  104. package/dist/modules/phone.js +110 -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 +169 -0
  119. package/dist/modules/speaker.d.ts.map +1 -0
  120. package/dist/modules/speaker.js +251 -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 +75 -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 +299 -0
  147. package/dist/protocol.d.ts.map +1 -0
  148. package/dist/protocol.js +325 -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 +312 -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 +207 -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 +84 -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 +242 -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 +291 -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 +155 -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 +335 -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 +145 -0
  257. package/src/modules/translation.ts +149 -0
  258. package/src/modules/ui.ts +498 -0
  259. package/src/protocol.ts +378 -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 +886 -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 +251 -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,207 @@
1
+ /**
2
+ * @fileoverview MockTransport — browser-tab fallback so the SDK doesn't hang.
3
+ *
4
+ * Activates when:
5
+ * - `window.ReactNativeWebView` is undefined (not in MentraOS WebView), AND
6
+ * - The first LocalSocketTransport connection attempt fails fast, OR
7
+ * - The author opts in via `?mentra=mock` query param / `localStorage.MENTRA_MOCK = "1"`.
8
+ *
9
+ * Behaviors:
10
+ * - On `open()`: synthesize a CONNECT_ACK envelope so `session.connect()` resolves.
11
+ * - On `send(envelope)`: parse, log to console with `[mock-transport]` prefix,
12
+ * auto-reply with synthetic results for any request that needs one.
13
+ * - Does NOT emit any glasses events. Subscribing succeeds silently.
14
+ *
15
+ * This is the Stage-1 stopgap from `agents/miniapp-quick-fixes-spec.md` #6.
16
+ * The full simulator (event injection, glasses-display preview, hardware bridge)
17
+ * is Stage 2 — see `agents/miniapp-browser-testing-simulator-spec.md`.
18
+ */
19
+ import { parseEnvelope, serializeEnvelope } from "../envelope";
20
+ import { MiniappRequestType, MiniappResponseType } from "../protocol";
21
+ const LOG_PREFIX = "[mock-transport]";
22
+ /**
23
+ * Returns true if the current environment requested the mock transport
24
+ * explicitly. Checks `?mentra=mock` query param and `localStorage.MENTRA_MOCK`.
25
+ */
26
+ export function isMockExplicitlyRequested() {
27
+ if (typeof window === "undefined")
28
+ return false;
29
+ try {
30
+ if (typeof window.location !== "undefined" && window.location.search) {
31
+ const params = new URLSearchParams(window.location.search);
32
+ if (params.get("mentra") === "mock")
33
+ return true;
34
+ }
35
+ }
36
+ catch {
37
+ // ignore
38
+ }
39
+ try {
40
+ if (typeof localStorage !== "undefined" && localStorage.getItem("MENTRA_MOCK") === "1") {
41
+ return true;
42
+ }
43
+ }
44
+ catch {
45
+ // localStorage may throw in some embedded contexts; ignore
46
+ }
47
+ return false;
48
+ }
49
+ export class MockTransport {
50
+ constructor(options = {}) {
51
+ this.messageHandler = null;
52
+ this.disconnectHandler = null;
53
+ this.open_ = false;
54
+ this.userId = options.userId ?? "mock-user";
55
+ this.authToken = options.authToken ?? "mock-miniapp-token";
56
+ this.packageName = options.packageName ?? null;
57
+ this.silent = options.silent === true;
58
+ }
59
+ async open() {
60
+ if (this.open_)
61
+ return;
62
+ this.open_ = true;
63
+ this.log("transport opened (no real host; synthetic responses only)");
64
+ }
65
+ send(raw) {
66
+ if (!this.open_) {
67
+ throw new Error("MockTransport: send() before open()");
68
+ }
69
+ const envelope = parseEnvelope(raw);
70
+ if (!envelope) {
71
+ this.log("dropped unparseable envelope:", raw.slice(0, 200));
72
+ return;
73
+ }
74
+ const payload = envelope.payload;
75
+ const type = payload?.type;
76
+ this.log(`recv ${type ?? "<unknown>"}${envelope.requestId ? ` (rid=${envelope.requestId})` : ""}`);
77
+ // Handle the protocol's synchronous handshake/responses.
78
+ switch (type) {
79
+ case MiniappRequestType.CONNECT:
80
+ this.deliverConnectAck(payload);
81
+ return;
82
+ case MiniappRequestType.PING:
83
+ // Real phone sends PING. We never do — but if app code somehow does,
84
+ // ignore it. The SDK auto-replies to inbound PINGs, not vice versa.
85
+ return;
86
+ case MiniappRequestType.SUBSCRIBE:
87
+ // Subscribe is fire-and-forget; no response expected. Stage 1 emits no
88
+ // events. Future Stage 2 simulator can synthesize events here.
89
+ return;
90
+ default:
91
+ // Anything that has a requestId expects a REQUEST_RESULT. Reply with a
92
+ // synthetic empty success so app code that awaits the promise resolves.
93
+ if (envelope.requestId) {
94
+ this.deliverSyntheticResult(envelope.requestId, type ?? "<unknown>", payload);
95
+ }
96
+ return;
97
+ }
98
+ }
99
+ onMessage(handler) {
100
+ this.messageHandler = handler;
101
+ }
102
+ onDisconnect(handler) {
103
+ this.disconnectHandler = handler;
104
+ }
105
+ close() {
106
+ if (!this.open_)
107
+ return;
108
+ this.open_ = false;
109
+ this.disconnectHandler?.("MockTransport.close()");
110
+ }
111
+ isOpen() {
112
+ return this.open_;
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ deliverConnectAck(connectPayload) {
116
+ const incomingPackage = connectPayload.packageName ?? this.packageName ?? "com.mock.app";
117
+ const ackPayload = {
118
+ type: MiniappResponseType.CONNECT_ACK,
119
+ userId: this.userId,
120
+ packageName: incomingPackage,
121
+ capabilities: null,
122
+ visibility: "foreground",
123
+ colorScheme: "light",
124
+ auth: {
125
+ mentraUserId: this.userId,
126
+ oemId: "mock",
127
+ token: this.authToken,
128
+ expiresAt: Date.now() + 60 * 60 * 1000,
129
+ },
130
+ };
131
+ const envelope = { payload: ackPayload };
132
+ this.log(`-> CONNECT_ACK userId=${this.userId} pkg=${incomingPackage}`);
133
+ // Deliver asynchronously so it doesn't fire during the same tick as send().
134
+ queueMicrotask(() => this.messageHandler?.(serializeEnvelope(envelope)));
135
+ }
136
+ deliverSyntheticResult(requestId, requestType, requestPayload) {
137
+ const data = syntheticDataFor(requestId, requestType, requestPayload);
138
+ const responsePayload = {
139
+ type: MiniappResponseType.REQUEST_RESULT,
140
+ ok: true,
141
+ data,
142
+ };
143
+ const envelope = { payload: responsePayload, requestId };
144
+ this.log(`-> REQUEST_RESULT (rid=${requestId}) synthetic ${requestType}`);
145
+ queueMicrotask(() => this.messageHandler?.(serializeEnvelope(envelope)));
146
+ }
147
+ log(...args) {
148
+ if (this.silent)
149
+ return;
150
+ console.log(LOG_PREFIX, ...args);
151
+ }
152
+ }
153
+ /**
154
+ * Synthetic payload for an unrecognized request that nonetheless awaits a
155
+ * REQUEST_RESULT. Returns enough shape to satisfy callers without crashing.
156
+ */
157
+ function syntheticDataFor(requestId, requestType, requestPayload) {
158
+ switch (requestType) {
159
+ case MiniappRequestType.CAMERA_FOV: {
160
+ const presetFov = requestPayload.preset === "narrow"
161
+ ? 82
162
+ : requestPayload.preset === "wide"
163
+ ? 118
164
+ : requestPayload.preset === "standard"
165
+ ? 102
166
+ : undefined;
167
+ const fov = typeof requestPayload.fov === "number" ? requestPayload.fov : (presetFov ?? 102);
168
+ const roi = requestPayload.roiPosition;
169
+ const roiPosition = roi === "bottom" ? "bottom" : roi === "top" ? "top" : "center";
170
+ return {
171
+ requestId,
172
+ fov,
173
+ roiPosition,
174
+ timestamp: Date.now(),
175
+ };
176
+ }
177
+ case MiniappRequestType.PHOTO:
178
+ // 1×1 transparent PNG so consumers that try to render don't 404.
179
+ return {
180
+ photoUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkAAIAAAoAAv/lxKUAAAAASUVORK5CYII=",
181
+ requestId: "mock-photo",
182
+ };
183
+ case MiniappRequestType.RGB_LED:
184
+ return { type: "rgb_led_control_response", state: "success", requestId };
185
+ case MiniappRequestType.LOCATION_POLL:
186
+ // San Francisco fallback — using 0,0 puts dev sessions in the
187
+ // Atlantic, which makes maps/navigation unusable in the WebView.
188
+ return { lat: 37.7956, lng: -122.3933, accuracy: 0, timestamp: Date.now() };
189
+ case MiniappRequestType.CALENDAR_LIST_EVENTS:
190
+ return { events: [], truncated: false };
191
+ case MiniappRequestType.STORAGE_GET:
192
+ return { value: null };
193
+ case MiniappRequestType.STORAGE_LIST:
194
+ return { keys: [] };
195
+ case MiniappRequestType.SPEAK:
196
+ return { audioUrl: null, durationMs: 0 };
197
+ case MiniappRequestType.SHARE:
198
+ case MiniappRequestType.OPEN_URL:
199
+ case MiniappRequestType.COPY_CLIPBOARD:
200
+ case MiniappRequestType.DOWNLOAD:
201
+ case MiniappRequestType.REQUEST_WIFI_SETUP:
202
+ return { ok: true };
203
+ default:
204
+ return null;
205
+ }
206
+ }
207
+ //# sourceMappingURL=mock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock.js","sourceRoot":"","sources":["../../src/transport/mock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAC,aAAa,EAAE,iBAAiB,EAAuB,MAAM,aAAa,CAAA;AAClF,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,aAAa,CAAA;AAGnE,MAAM,UAAU,GAAG,kBAAkB,CAAA;AAErC;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACvC,IAAI,OAAO,MAAM,KAAK,WAAW;QAAE,OAAO,KAAK,CAAA;IAC/C,IAAI,CAAC;QACH,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;YAC1D,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAA;QAClD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;IACD,IAAI,CAAC;QACH,IAAI,OAAO,YAAY,KAAK,WAAW,IAAI,YAAY,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,GAAG,EAAE,CAAC;YACvF,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAaD,MAAM,OAAO,aAAa;IASxB,YAAY,UAAgC,EAAE;QARtC,mBAAc,GAAmC,IAAI,CAAA;QACrD,sBAAiB,GAAsC,IAAI,CAAA;QAC3D,UAAK,GAAG,KAAK,CAAA;QAOnB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,WAAW,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,oBAAoB,CAAA;QAC1D,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAA;QAC9C,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,IAAI,CAAA;IACvC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAA;IACvE,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;QACxD,CAAC;QACD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,+BAA+B,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YAC5D,OAAM;QACR,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAoD,CAAA;QAC7E,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,CAAA;QAC1B,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAElG,yDAAyD;QACzD,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,kBAAkB,CAAC,OAAO;gBAC7B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAA;gBAC/B,OAAM;YAER,KAAK,kBAAkB,CAAC,IAAI;gBAC1B,qEAAqE;gBACrE,oEAAoE;gBACpE,OAAM;YAER,KAAK,kBAAkB,CAAC,SAAS;gBAC/B,uEAAuE;gBACvE,+DAA+D;gBAC/D,OAAM;YAER;gBACE,uEAAuE;gBACvE,wEAAwE;gBACxE,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;oBACvB,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,IAAI,WAAW,EAAE,OAAO,CAAC,CAAA;gBAC/E,CAAC;gBACD,OAAM;QACV,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAAgC;QACxC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAA;IAC/B,CAAC;IAED,YAAY,CAAC,OAAmC;QAC9C,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAA;IAClC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,iBAAiB,EAAE,CAAC,uBAAuB,CAAC,CAAA;IACnD,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,8EAA8E;IAEtE,iBAAiB,CAAC,cAAuC;QAC/D,MAAM,eAAe,GAAI,cAAc,CAAC,WAAkC,IAAI,IAAI,CAAC,WAAW,IAAI,cAAc,CAAA;QAChH,MAAM,UAAU,GAAG;YACjB,IAAI,EAAE,mBAAmB,CAAC,WAAW;YACrC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW,EAAE,eAAe;YAC5B,YAAY,EAAE,IAAI;YAClB,UAAU,EAAE,YAAY;YACxB,WAAW,EAAE,OAAO;YACpB,IAAI,EAAE;gBACJ,YAAY,EAAE,IAAI,CAAC,MAAM;gBACzB,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,IAAI,CAAC,SAAS;gBACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;aACvC;SACF,CAAA;QACD,MAAM,QAAQ,GAAoB,EAAC,OAAO,EAAE,UAAU,EAAC,CAAA;QACvD,IAAI,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,MAAM,QAAQ,eAAe,EAAE,CAAC,CAAA;QACvE,4EAA4E;QAC5E,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;IAEO,sBAAsB,CAC5B,SAAiB,EACjB,WAAmB,EACnB,cAAuC;QAEvC,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,EAAE,WAAW,EAAE,cAAc,CAAC,CAAA;QACrE,MAAM,eAAe,GAAG;YACtB,IAAI,EAAE,mBAAmB,CAAC,cAAc;YACxC,EAAE,EAAE,IAAI;YACR,IAAI;SACL,CAAA;QACD,MAAM,QAAQ,GAAoB,EAAC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAC,CAAA;QACvE,IAAI,CAAC,GAAG,CAAC,0BAA0B,SAAS,eAAe,WAAW,EAAE,CAAC,CAAA;QACzE,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC1E,CAAC;IAEO,GAAG,CAAC,GAAG,IAAe;QAC5B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAM;QAEvB,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAA;IAClC,CAAC;CACF;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,SAAiB,EAAE,WAAmB,EAAE,cAAuC;IACvG,QAAQ,WAAW,EAAE,CAAC;QACpB,KAAK,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC;YACnC,MAAM,SAAS,GACb,cAAc,CAAC,MAAM,KAAK,QAAQ;gBAChC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,cAAc,CAAC,MAAM,KAAK,MAAM;oBAChC,CAAC,CAAC,GAAG;oBACL,CAAC,CAAC,cAAc,CAAC,MAAM,KAAK,UAAU;wBACpC,CAAC,CAAC,GAAG;wBACL,CAAC,CAAC,SAAS,CAAA;YACnB,MAAM,GAAG,GAAG,OAAO,cAAc,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,CAAA;YAC5F,MAAM,GAAG,GAAG,cAAc,CAAC,WAAW,CAAA;YACtC,MAAM,WAAW,GAAG,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAA;YAClF,OAAO;gBACL,SAAS;gBACT,GAAG;gBACH,WAAW;gBACX,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAA;QACH,CAAC;QAED,KAAK,kBAAkB,CAAC,KAAK;YAC3B,iEAAiE;YACjE,OAAO;gBACL,QAAQ,EACN,oHAAoH;gBACtH,SAAS,EAAE,YAAY;aACxB,CAAA;QAEH,KAAK,kBAAkB,CAAC,OAAO;YAC7B,OAAO,EAAC,IAAI,EAAE,0BAA0B,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAC,CAAA;QAExE,KAAK,kBAAkB,CAAC,aAAa;YACnC,8DAA8D;YAC9D,iEAAiE;YACjE,OAAO,EAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAC,CAAA;QAE3E,KAAK,kBAAkB,CAAC,oBAAoB;YAC1C,OAAO,EAAC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAC,CAAA;QAEvC,KAAK,kBAAkB,CAAC,WAAW;YACjC,OAAO,EAAC,KAAK,EAAE,IAAI,EAAC,CAAA;QAEtB,KAAK,kBAAkB,CAAC,YAAY;YAClC,OAAO,EAAC,IAAI,EAAE,EAAE,EAAC,CAAA;QAEnB,KAAK,kBAAkB,CAAC,KAAK;YAC3B,OAAO,EAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAC,CAAA;QAExC,KAAK,kBAAkB,CAAC,KAAK,CAAC;QAC9B,KAAK,kBAAkB,CAAC,QAAQ,CAAC;QACjC,KAAK,kBAAkB,CAAC,cAAc,CAAC;QACvC,KAAK,kBAAkB,CAAC,QAAQ,CAAC;QACjC,KAAK,kBAAkB,CAAC,kBAAkB;YACxC,OAAO,EAAC,EAAE,EAAE,IAAI,EAAC,CAAA;QAEnB;YACE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @fileoverview PostMessage transport — in-WebView bridge via React Native WebView.
3
+ *
4
+ * The React Native WebView exposes:
5
+ * - window.ReactNativeWebView.postMessage(string): miniapp → phone
6
+ * - document "message" events + window "message" events: phone → miniapp
7
+ *
8
+ * react-native-webview sends incoming messages as regular DOM `MessageEvent`s
9
+ * on the `window` object, with `event.data` as the string payload. We listen
10
+ * there.
11
+ *
12
+ * Old MentraOS builds injected a global `window.receiveNativeMessage` function;
13
+ * we also accept that path for compatibility by assigning our handler to it.
14
+ */
15
+ import { Transport, TransportDisconnectHandler, TransportMessageHandler } from "./types";
16
+ declare global {
17
+ interface Window {
18
+ ReactNativeWebView?: {
19
+ postMessage: (data: string) => void;
20
+ };
21
+ receiveNativeMessage?: (raw: string) => void;
22
+ }
23
+ }
24
+ export declare class PostMessageTransport implements Transport {
25
+ private messageHandler;
26
+ private disconnectHandler;
27
+ private open_;
28
+ private windowListener;
29
+ open(): Promise<void>;
30
+ send(raw: string): void;
31
+ onMessage(handler: TransportMessageHandler): void;
32
+ onDisconnect(handler: TransportDisconnectHandler): void;
33
+ close(): void;
34
+ isOpen(): boolean;
35
+ }
36
+ //# sourceMappingURL=postmessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postmessage.d.ts","sourceRoot":"","sources":["../../src/transport/postmessage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAC,SAAS,EAAE,0BAA0B,EAAE,uBAAuB,EAAC,MAAM,SAAS,CAAA;AAItF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,kBAAkB,CAAC,EAAE;YACnB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;SACpC,CAAA;QACD,oBAAoB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;KAC7C;CACF;AAED,qBAAa,oBAAqB,YAAW,SAAS;IACpD,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,iBAAiB,CAA0C;IACnE,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,cAAc,CAA4C;IAE5D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B3B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOvB,SAAS,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI;IAIjD,YAAY,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAIvD,KAAK,IAAI,IAAI;IAgBb,MAAM,IAAI,OAAO;CAGlB"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @fileoverview PostMessage transport — in-WebView bridge via React Native WebView.
3
+ *
4
+ * The React Native WebView exposes:
5
+ * - window.ReactNativeWebView.postMessage(string): miniapp → phone
6
+ * - document "message" events + window "message" events: phone → miniapp
7
+ *
8
+ * react-native-webview sends incoming messages as regular DOM `MessageEvent`s
9
+ * on the `window` object, with `event.data` as the string payload. We listen
10
+ * there.
11
+ *
12
+ * Old MentraOS builds injected a global `window.receiveNativeMessage` function;
13
+ * we also accept that path for compatibility by assigning our handler to it.
14
+ */
15
+ export class PostMessageTransport {
16
+ constructor() {
17
+ this.messageHandler = null;
18
+ this.disconnectHandler = null;
19
+ this.open_ = false;
20
+ this.windowListener = null;
21
+ }
22
+ async open() {
23
+ if (this.open_)
24
+ return;
25
+ if (typeof window === "undefined" || !window.ReactNativeWebView) {
26
+ throw new Error("PostMessageTransport: not running inside a React Native WebView");
27
+ }
28
+ // Listen on window "message" — react-native-webview routes host→webview
29
+ // messages here. Also some builds dispatch on document; hook both.
30
+ this.windowListener = (ev) => {
31
+ const data = ev.data;
32
+ if (typeof data !== "string")
33
+ return;
34
+ this.messageHandler?.(data);
35
+ };
36
+ window.addEventListener("message", this.windowListener);
37
+ if (typeof document !== "undefined") {
38
+ document.addEventListener("message", this.windowListener);
39
+ }
40
+ // Legacy path: some host code calls window.receiveNativeMessage directly.
41
+ window.receiveNativeMessage = (raw) => {
42
+ this.messageHandler?.(raw);
43
+ };
44
+ this.open_ = true;
45
+ }
46
+ send(raw) {
47
+ if (typeof window === "undefined" || !window.ReactNativeWebView) {
48
+ throw new Error("PostMessageTransport: not running inside a React Native WebView");
49
+ }
50
+ window.ReactNativeWebView.postMessage(raw);
51
+ }
52
+ onMessage(handler) {
53
+ this.messageHandler = handler;
54
+ }
55
+ onDisconnect(handler) {
56
+ this.disconnectHandler = handler;
57
+ }
58
+ close() {
59
+ if (!this.open_)
60
+ return;
61
+ this.open_ = false;
62
+ if (this.windowListener) {
63
+ window.removeEventListener("message", this.windowListener);
64
+ if (typeof document !== "undefined") {
65
+ document.removeEventListener("message", this.windowListener);
66
+ }
67
+ this.windowListener = null;
68
+ }
69
+ if (typeof window !== "undefined" && window.receiveNativeMessage) {
70
+ window.receiveNativeMessage = undefined;
71
+ }
72
+ this.disconnectHandler?.("closed");
73
+ }
74
+ isOpen() {
75
+ return this.open_;
76
+ }
77
+ }
78
+ //# sourceMappingURL=postmessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postmessage.js","sourceRoot":"","sources":["../../src/transport/postmessage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAeH,MAAM,OAAO,oBAAoB;IAAjC;QACU,mBAAc,GAAmC,IAAI,CAAA;QACrD,sBAAiB,GAAsC,IAAI,CAAA;QAC3D,UAAK,GAAG,KAAK,CAAA;QACb,mBAAc,GAAwC,IAAI,CAAA;IA8DpE,CAAC;IA5DC,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QACtB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;QACpF,CAAC;QAED,wEAAwE;QACxE,mEAAmE;QACnE,IAAI,CAAC,cAAc,GAAG,CAAC,EAAgB,EAAE,EAAE;YACzC,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAA;YACpB,IAAI,OAAO,IAAI,KAAK,QAAQ;gBAAE,OAAM;YACpC,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC,CAAA;QACD,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QACvD,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;YACpC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,cAA0C,CAAC,CAAA;QACvF,CAAC;QAED,0EAA0E;QAC1E,MAAM,CAAC,oBAAoB,GAAG,CAAC,GAAW,EAAE,EAAE;YAC5C,IAAI,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAA;QAC5B,CAAC,CAAA;QAED,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;IACnB,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAChE,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAA;QACpF,CAAC;QACD,MAAM,CAAC,kBAAkB,CAAC,WAAW,CAAC,GAAG,CAAC,CAAA;IAC5C,CAAC;IAED,SAAS,CAAC,OAAgC;QACxC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAA;IAC/B,CAAC;IAED,YAAY,CAAC,OAAmC;QAC9C,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAA;IAClC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAM;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YAC1D,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACpC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,cAA0C,CAAC,CAAA;YAC1F,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAA;QAC5B,CAAC;QACD,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACjE,MAAM,CAAC,oBAAoB,GAAG,SAAS,CAAA;QACzC,CAAC;QACD,IAAI,CAAC,iBAAiB,EAAE,CAAC,QAAQ,CAAC,CAAA;IACpC,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;CACF"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @fileoverview Transport abstraction for @mentra/miniapp.
3
+ *
4
+ * Two v1 implementations:
5
+ * - PostMessageTransport — inside MentraOS WebView, uses window.ReactNativeWebView
6
+ * - LocalSocketTransport — in external Safari/Chrome fallback, uses ws://127.0.0.1
7
+ *
8
+ * createTransport() in auto.ts picks the right one based on environment.
9
+ */
10
+ export type TransportMessageHandler = (raw: string) => void;
11
+ export type TransportDisconnectHandler = (reason: string) => void;
12
+ export interface Transport {
13
+ /** Establish whatever connection the transport needs. May be a no-op. */
14
+ open(): Promise<void>;
15
+ /** Send a serialized envelope. */
16
+ send(raw: string): void;
17
+ /** Register a callback for incoming serialized envelopes. */
18
+ onMessage(handler: TransportMessageHandler): void;
19
+ /** Register a callback for transport-level disconnects / errors. */
20
+ onDisconnect(handler: TransportDisconnectHandler): void;
21
+ /** Close the transport cleanly. Idempotent. */
22
+ close(): void;
23
+ isOpen(): boolean;
24
+ }
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;AAC3D,MAAM,MAAM,0BAA0B,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;AAEjE,MAAM,WAAW,SAAS;IACxB,yEAAyE;IACzE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,kCAAkC;IAClC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,6DAA6D;IAC7D,SAAS,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAA;IACjD,oEAAoE;IACpE,YAAY,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAAA;IACvD,+CAA+C;IAC/C,KAAK,IAAI,IAAI,CAAA;IACb,MAAM,IAAI,OAAO,CAAA;CAClB"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Transport abstraction for @mentra/miniapp.
3
+ *
4
+ * Two v1 implementations:
5
+ * - PostMessageTransport — inside MentraOS WebView, uses window.ReactNativeWebView
6
+ * - LocalSocketTransport — in external Safari/Chrome fallback, uses ws://127.0.0.1
7
+ *
8
+ * createTransport() in auto.ts picks the right one based on environment.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @mentra/miniapp/ui — WebView-side SDK entry point.
3
+ *
4
+ * Imported from a miniapp's `src/ui/main.tsx` (or equivalent) to access
5
+ * the `mentra` WebView global, React hooks, and the `MentraProvider`
6
+ * wrapper. This is the **on-demand WebView side** of a two-layer miniapp.
7
+ *
8
+ * What's NOT in this entry point:
9
+ * - `MiniappSession` — background-only.
10
+ * - Any `session.*` module classes — background-only.
11
+ * - `__dispatch` / direct native access — by design, the WebView has
12
+ * no host-native APIs. All hardware calls go through the background
13
+ * bus via `mentra.send(channel, payload)`.
14
+ *
15
+ * The `mentra` global is injected into every UI WebView at mount time
16
+ * by the host's `mentraUiShim` (see `@mentra/engine/services/mentraUiShim`).
17
+ * This entry point exports its TypeScript declaration so authors get
18
+ * autocomplete and compile-time errors on channel names + payloads.
19
+ */
20
+ import type { IsRpc, RpcReq, RpcRes, RpcRequestOptions } from "../modules/ui";
21
+ export type { Rpc, IsRpc, RpcReq, RpcRes, RpcRequestOptions, RpcHandlerContext } from "../modules/ui";
22
+ export { MentraRpcError, MentraRpcTimeoutError } from "../modules/ui";
23
+ export interface MentraUiGlobal<TChannels extends object = Record<string, unknown>> {
24
+ /**
25
+ * Broadcast a typed message to the bound background JSContext.
26
+ * Buffered until `ready()` acks; once acked, fires immediately.
27
+ * Compile-error if `C` is an RPC channel — use `request()` instead.
28
+ */
29
+ send<C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? never : C, payload: TChannels[C]): void;
30
+ /**
31
+ * Subscribe to broadcast messages from the background. Compile-error
32
+ * if `C` is an RPC channel.
33
+ */
34
+ on<C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? never : C, cb: (payload: TChannels[C]) => void): () => void;
35
+ /**
36
+ * Make an RPC call to the background `session.ui.handle(channel, ...)`
37
+ * handler. On failure, throws an `Error` whose `name` is one of:
38
+ * - `"MentraRpcError"` — the handler threw. `err.cause?.code` may be set.
39
+ * - `"MentraRpcTimeoutError"` — `options.timeout` elapsed.
40
+ * - `"AbortError"` — `options.signal` aborted.
41
+ * Distinguish by `err.name`, not `instanceof` — these errors are
42
+ * constructed in the WebView's bare runtime scope. No default timeout.
43
+ */
44
+ request<C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? C : never, payload: RpcReq<TChannels[C]>, options?: RpcRequestOptions): Promise<RpcRes<TChannels[C]>>;
45
+ /**
46
+ * Fires when the bridge is open and `mentra.send` is flushable. If
47
+ * subscribed AFTER `ready()` has been called, fires immediately.
48
+ */
49
+ onOpen(cb: () => void): () => void;
50
+ /**
51
+ * Fires when the host is about to destroy the WebView. Handlers
52
+ * should snapshot any session state into background via
53
+ * `mentra.send` if they want it to survive.
54
+ */
55
+ onClose(cb: () => void): () => void;
56
+ /**
57
+ * MUST be called once on UI bootstrap. Tells the host the WebView is
58
+ * mounted and ready to receive messages from background. Idempotent
59
+ * — subsequent calls no-op. Background's `session.ui.onOpen` handlers
60
+ * fire after this lands.
61
+ */
62
+ ready(): void;
63
+ }
64
+ export { MentraProvider, type MentraProviderProps, } from "../react/MentraProvider";
65
+ export { MiniappHeader } from "../react/MiniappHeader";
66
+ export { useColorScheme } from "../react/useColorScheme";
67
+ export { useCapabilities } from "../react/useCapabilities";
68
+ export { useConnected } from "../react/useConnected";
69
+ export { useSafeArea } from "../react/useSafeArea";
70
+ export { useCapsuleHeaderStyle } from "../react/useCapsuleHeaderStyle";
71
+ export { useRpc, type RpcCallable } from "../react/useRpc";
72
+ /**
73
+ * Type helper for declaring a typed `mentra` global inside a miniapp.
74
+ *
75
+ * Every mini app should declare ONE global `mentra` typed against its
76
+ * own channel registry. The SDK no longer auto-declares the global so
77
+ * each miniapp's registry doesn't collide with the SDK's default.
78
+ *
79
+ * Usage (in your miniapp's `src/shared/channels.ts`):
80
+ *
81
+ * ```ts
82
+ * import type {MentraTyped} from "@mentra/miniapp/ui"
83
+ *
84
+ * export interface Channels {
85
+ * "live-transcript": {text: string}
86
+ * }
87
+ *
88
+ * declare global {
89
+ * // eslint-disable-next-line no-var
90
+ * var mentra: MentraTyped<Channels>
91
+ * }
92
+ * ```
93
+ *
94
+ * Both halves of the miniapp (background + UI) import this same file,
95
+ * so the typed shape is consistent across the bridge.
96
+ */
97
+ export type MentraTyped<TChannels extends object> = MentraUiGlobal<TChannels>;
98
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAC,MAAM,eAAe,CAAA;AAC3E,YAAY,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,eAAe,CAAA;AACnG,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAC,MAAM,eAAe,CAAA;AAEnE,MAAM,WAAW,cAAc,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChF;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,MAAM,EACrC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,EACrD,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,GACpB,IAAI,CAAA;IAEP;;;OAGG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,MAAM,EACnC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,EACrD,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,GAClC,MAAM,IAAI,CAAA;IAEb;;;;;;;;OAQG;IACH,OAAO,CAAC,CAAC,SAAS,MAAM,SAAS,GAAG,MAAM,EACxC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK,EACrD,OAAO,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAC7B,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEhC;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAElC;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAEnC;;;;;OAKG;IACH,KAAK,IAAI,IAAI,CAAA;CACd;AAKD,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAC,qBAAqB,EAAC,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAC,MAAM,EAAE,KAAK,WAAW,EAAC,MAAM,iBAAiB,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,MAAM,IAAI,cAAc,CAAC,SAAS,CAAC,CAAA"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @mentra/miniapp/ui — WebView-side SDK entry point.
3
+ *
4
+ * Imported from a miniapp's `src/ui/main.tsx` (or equivalent) to access
5
+ * the `mentra` WebView global, React hooks, and the `MentraProvider`
6
+ * wrapper. This is the **on-demand WebView side** of a two-layer miniapp.
7
+ *
8
+ * What's NOT in this entry point:
9
+ * - `MiniappSession` — background-only.
10
+ * - Any `session.*` module classes — background-only.
11
+ * - `__dispatch` / direct native access — by design, the WebView has
12
+ * no host-native APIs. All hardware calls go through the background
13
+ * bus via `mentra.send(channel, payload)`.
14
+ *
15
+ * The `mentra` global is injected into every UI WebView at mount time
16
+ * by the host's `mentraUiShim` (see `@mentra/engine/services/mentraUiShim`).
17
+ * This entry point exports its TypeScript declaration so authors get
18
+ * autocomplete and compile-time errors on channel names + payloads.
19
+ */
20
+ export { MentraRpcError, MentraRpcTimeoutError } from "../modules/ui";
21
+ // React adapters are re-exported here so authors can import everything
22
+ // from a single sub-path. The actual hooks live in src/react/ and are
23
+ // already shipped as a separate sub-path for backwards-compat.
24
+ export { MentraProvider, } from "../react/MentraProvider";
25
+ export { MiniappHeader } from "../react/MiniappHeader";
26
+ export { useColorScheme } from "../react/useColorScheme";
27
+ export { useCapabilities } from "../react/useCapabilities";
28
+ export { useConnected } from "../react/useConnected";
29
+ export { useSafeArea } from "../react/useSafeArea";
30
+ export { useCapsuleHeaderStyle } from "../react/useCapsuleHeaderStyle";
31
+ export { useRpc } from "../react/useRpc";
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAC,cAAc,EAAE,qBAAqB,EAAC,MAAM,eAAe,CAAA;AA2DnE,uEAAuE;AACvE,sEAAsE;AACtE,+DAA+D;AAC/D,OAAO,EACL,cAAc,GAEf,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAA;AAClD,OAAO,EAAC,WAAW,EAAC,MAAM,sBAAsB,CAAA;AAChD,OAAO,EAAC,qBAAqB,EAAC,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAC,MAAM,EAAmB,MAAM,iBAAiB,CAAA"}
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@mentra/miniapp",
3
+ "version": "0.3.0-beta.0",
4
+ "description": "SDK for building MentraOS local miniapps (browser/WebView)",
5
+ "author": "Mentra Labs",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./background": {
17
+ "types": "./dist/background/index.d.ts",
18
+ "default": "./dist/background/index.js"
19
+ },
20
+ "./ui": {
21
+ "types": "./dist/ui/index.d.ts",
22
+ "default": "./dist/ui/index.js"
23
+ },
24
+ "./react": {
25
+ "types": "./dist/react/index.d.ts",
26
+ "default": "./dist/react/index.js"
27
+ },
28
+ "./protocol": {
29
+ "types": "./dist/protocol.d.ts",
30
+ "default": "./dist/protocol.js"
31
+ },
32
+ "./package.json": "./package.json"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public",
36
+ "tag": "dev"
37
+ },
38
+ "sideEffects": false,
39
+ "scripts": {
40
+ "build": "rm -rf dist tsconfig.tsbuildinfo && bun x tsc -p tsconfig.json",
41
+ "dev": "bun x tsc --watch",
42
+ "typecheck": "bun x tsc --noEmit",
43
+ "test": "bun test",
44
+ "prepare": "bun run build",
45
+ "prepublishOnly": "bun run build"
46
+ },
47
+ "peerDependencies": {
48
+ "react": ">=18.0.0"
49
+ },
50
+ "peerDependenciesMeta": {
51
+ "react": {
52
+ "optional": true
53
+ }
54
+ },
55
+ "dependencies": {
56
+ "@mentra/types": "1.0.0-beta.2",
57
+ "eventemitter3": "^5.0.1"
58
+ },
59
+ "devDependencies": {
60
+ "@types/react": "^19.1.6",
61
+ "react": "^19.1.0",
62
+ "typescript": "^5.0.0"
63
+ },
64
+ "files": [
65
+ "dist",
66
+ "src",
67
+ "!src/**/*.test.ts"
68
+ ],
69
+ "keywords": [
70
+ "mentra",
71
+ "mentraos",
72
+ "miniapp",
73
+ "smart-glasses"
74
+ ],
75
+ "repository": {
76
+ "type": "git",
77
+ "url": "git+https://github.com/Mentra-Community/MentraOS.git",
78
+ "directory": "mobile/modules/miniapp"
79
+ },
80
+ "homepage": "https://github.com/Mentra-Community/MentraOS/tree/dev/mobile/modules/miniapp#readme",
81
+ "bugs": {
82
+ "url": "https://github.com/Mentra-Community/MentraOS/issues"
83
+ }
84
+ }