@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.
- package/README.md +259 -0
- package/dist/background/index.d.ts +59 -0
- package/dist/background/index.d.ts.map +1 -0
- package/dist/background/index.js +25 -0
- package/dist/background/index.js.map +1 -0
- package/dist/background/register.d.ts +38 -0
- package/dist/background/register.d.ts.map +1 -0
- package/dist/background/register.js +75 -0
- package/dist/background/register.js.map +1 -0
- package/dist/dev-reload.d.ts +21 -0
- package/dist/dev-reload.d.ts.map +1 -0
- package/dist/dev-reload.js +62 -0
- package/dist/dev-reload.js.map +1 -0
- package/dist/envelope.d.ts +23 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +47 -0
- package/dist/envelope.js.map +1 -0
- package/dist/globals.d.ts +54 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +12 -0
- package/dist/globals.js.map +1 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/actions.d.ts +54 -0
- package/dist/modules/actions.d.ts.map +1 -0
- package/dist/modules/actions.js +122 -0
- package/dist/modules/actions.js.map +1 -0
- package/dist/modules/auth.d.ts +25 -0
- package/dist/modules/auth.d.ts.map +1 -0
- package/dist/modules/auth.js +52 -0
- package/dist/modules/auth.js.map +1 -0
- package/dist/modules/base64.d.ts +16 -0
- package/dist/modules/base64.d.ts.map +1 -0
- package/dist/modules/base64.js +92 -0
- package/dist/modules/base64.js.map +1 -0
- package/dist/modules/blob.d.ts +161 -0
- package/dist/modules/blob.d.ts.map +1 -0
- package/dist/modules/blob.js +277 -0
- package/dist/modules/blob.js.map +1 -0
- package/dist/modules/camera.d.ts +137 -0
- package/dist/modules/camera.d.ts.map +1 -0
- package/dist/modules/camera.js +104 -0
- package/dist/modules/camera.js.map +1 -0
- package/dist/modules/cloud.d.ts +34 -0
- package/dist/modules/cloud.d.ts.map +1 -0
- package/dist/modules/cloud.js +70 -0
- package/dist/modules/cloud.js.map +1 -0
- package/dist/modules/dashboard.d.ts +16 -0
- package/dist/modules/dashboard.d.ts.map +1 -0
- package/dist/modules/dashboard.js +27 -0
- package/dist/modules/dashboard.js.map +1 -0
- package/dist/modules/display.d.ts +106 -0
- package/dist/modules/display.d.ts.map +1 -0
- package/dist/modules/display.js +57 -0
- package/dist/modules/display.js.map +1 -0
- package/dist/modules/events.d.ts +167 -0
- package/dist/modules/events.d.ts.map +1 -0
- package/dist/modules/events.js +123 -0
- package/dist/modules/events.js.map +1 -0
- package/dist/modules/glasses.d.ts +28 -0
- package/dist/modules/glasses.d.ts.map +1 -0
- package/dist/modules/glasses.js +39 -0
- package/dist/modules/glasses.js.map +1 -0
- package/dist/modules/heading.d.ts +16 -0
- package/dist/modules/heading.d.ts.map +1 -0
- package/dist/modules/heading.js +20 -0
- package/dist/modules/heading.js.map +1 -0
- package/dist/modules/imu.d.ts +31 -0
- package/dist/modules/imu.d.ts.map +1 -0
- package/dist/modules/imu.js +40 -0
- package/dist/modules/imu.js.map +1 -0
- package/dist/modules/input.d.ts +34 -0
- package/dist/modules/input.d.ts.map +1 -0
- package/dist/modules/input.js +50 -0
- package/dist/modules/input.js.map +1 -0
- package/dist/modules/led.d.ts +35 -0
- package/dist/modules/led.d.ts.map +1 -0
- package/dist/modules/led.js +39 -0
- package/dist/modules/led.js.map +1 -0
- package/dist/modules/location.d.ts +27 -0
- package/dist/modules/location.d.ts.map +1 -0
- package/dist/modules/location.js +35 -0
- package/dist/modules/location.js.map +1 -0
- package/dist/modules/mic.d.ts +44 -0
- package/dist/modules/mic.d.ts.map +1 -0
- package/dist/modules/mic.js +67 -0
- package/dist/modules/mic.js.map +1 -0
- package/dist/modules/miniapps.d.ts +72 -0
- package/dist/modules/miniapps.d.ts.map +1 -0
- package/dist/modules/miniapps.js +48 -0
- package/dist/modules/miniapps.js.map +1 -0
- package/dist/modules/navigation.d.ts +326 -0
- package/dist/modules/navigation.d.ts.map +1 -0
- package/dist/modules/navigation.js +386 -0
- package/dist/modules/navigation.js.map +1 -0
- package/dist/modules/permissions.d.ts +58 -0
- package/dist/modules/permissions.d.ts.map +1 -0
- package/dist/modules/permissions.js +66 -0
- package/dist/modules/permissions.js.map +1 -0
- package/dist/modules/phone.d.ts +61 -0
- package/dist/modules/phone.d.ts.map +1 -0
- package/dist/modules/phone.js +94 -0
- package/dist/modules/phone.js.map +1 -0
- package/dist/modules/pivots/engine.d.ts +169 -0
- package/dist/modules/pivots/engine.d.ts.map +1 -0
- package/dist/modules/pivots/engine.js +779 -0
- package/dist/modules/pivots/engine.js.map +1 -0
- package/dist/modules/pivots/geometry.d.ts +84 -0
- package/dist/modules/pivots/geometry.d.ts.map +1 -0
- package/dist/modules/pivots/geometry.js +371 -0
- package/dist/modules/pivots/geometry.js.map +1 -0
- package/dist/modules/pivots/instructions.d.ts +139 -0
- package/dist/modules/pivots/instructions.d.ts.map +1 -0
- package/dist/modules/pivots/instructions.js +280 -0
- package/dist/modules/pivots/instructions.js.map +1 -0
- package/dist/modules/speaker.d.ts +163 -0
- package/dist/modules/speaker.d.ts.map +1 -0
- package/dist/modules/speaker.js +250 -0
- package/dist/modules/speaker.js.map +1 -0
- package/dist/modules/storage.d.ts +50 -0
- package/dist/modules/storage.d.ts.map +1 -0
- package/dist/modules/storage.js +99 -0
- package/dist/modules/storage.js.map +1 -0
- package/dist/modules/stream.d.ts +129 -0
- package/dist/modules/stream.d.ts.map +1 -0
- package/dist/modules/stream.js +52 -0
- package/dist/modules/stream.js.map +1 -0
- package/dist/modules/system.d.ts +45 -0
- package/dist/modules/system.d.ts.map +1 -0
- package/dist/modules/system.js +42 -0
- package/dist/modules/system.js.map +1 -0
- package/dist/modules/transcription.d.ts +67 -0
- package/dist/modules/transcription.d.ts.map +1 -0
- package/dist/modules/transcription.js +106 -0
- package/dist/modules/transcription.js.map +1 -0
- package/dist/modules/translation.d.ts +59 -0
- package/dist/modules/translation.d.ts.map +1 -0
- package/dist/modules/translation.js +119 -0
- package/dist/modules/translation.js.map +1 -0
- package/dist/modules/ui.d.ts +186 -0
- package/dist/modules/ui.d.ts.map +1 -0
- package/dist/modules/ui.js +293 -0
- package/dist/modules/ui.js.map +1 -0
- package/dist/protocol.d.ts +294 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +320 -0
- package/dist/protocol.js.map +1 -0
- package/dist/react/MentraProvider.d.ts +33 -0
- package/dist/react/MentraProvider.d.ts.map +1 -0
- package/dist/react/MentraProvider.js +15 -0
- package/dist/react/MentraProvider.js.map +1 -0
- package/dist/react/MiniappHeader.d.ts +44 -0
- package/dist/react/MiniappHeader.d.ts.map +1 -0
- package/dist/react/MiniappHeader.js +32 -0
- package/dist/react/MiniappHeader.js.map +1 -0
- package/dist/react/index.d.ts +13 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +9 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/useCapabilities.d.ts +26 -0
- package/dist/react/useCapabilities.d.ts.map +1 -0
- package/dist/react/useCapabilities.js +27 -0
- package/dist/react/useCapabilities.js.map +1 -0
- package/dist/react/useCapsuleHeaderStyle.d.ts +27 -0
- package/dist/react/useCapsuleHeaderStyle.d.ts.map +1 -0
- package/dist/react/useCapsuleHeaderStyle.js +36 -0
- package/dist/react/useCapsuleHeaderStyle.js.map +1 -0
- package/dist/react/useColorScheme.d.ts +18 -0
- package/dist/react/useColorScheme.d.ts.map +1 -0
- package/dist/react/useColorScheme.js +24 -0
- package/dist/react/useColorScheme.js.map +1 -0
- package/dist/react/useConnected.d.ts +17 -0
- package/dist/react/useConnected.d.ts.map +1 -0
- package/dist/react/useConnected.js +39 -0
- package/dist/react/useConnected.js.map +1 -0
- package/dist/react/useRpc.d.ts +29 -0
- package/dist/react/useRpc.d.ts.map +1 -0
- package/dist/react/useRpc.js +82 -0
- package/dist/react/useRpc.js.map +1 -0
- package/dist/react/useSafeArea.d.ts +21 -0
- package/dist/react/useSafeArea.d.ts.map +1 -0
- package/dist/react/useSafeArea.js +22 -0
- package/dist/react/useSafeArea.js.map +1 -0
- package/dist/session.d.ts +310 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +653 -0
- package/dist/session.js.map +1 -0
- package/dist/sub-path-types.test-d.d.ts +28 -0
- package/dist/sub-path-types.test-d.d.ts.map +1 -0
- package/dist/sub-path-types.test-d.js +37 -0
- package/dist/sub-path-types.test-d.js.map +1 -0
- package/dist/transport/auto.d.ts +35 -0
- package/dist/transport/auto.d.ts.map +1 -0
- package/dist/transport/auto.js +125 -0
- package/dist/transport/auto.js.map +1 -0
- package/dist/transport/dispatch.d.ts +43 -0
- package/dist/transport/dispatch.d.ts.map +1 -0
- package/dist/transport/dispatch.js +91 -0
- package/dist/transport/dispatch.js.map +1 -0
- package/dist/transport/local-socket.d.ts +28 -0
- package/dist/transport/local-socket.d.ts.map +1 -0
- package/dist/transport/local-socket.js +80 -0
- package/dist/transport/local-socket.js.map +1 -0
- package/dist/transport/mock.d.ts +54 -0
- package/dist/transport/mock.d.ts.map +1 -0
- package/dist/transport/mock.js +205 -0
- package/dist/transport/mock.js.map +1 -0
- package/dist/transport/postmessage.d.ts +36 -0
- package/dist/transport/postmessage.d.ts.map +1 -0
- package/dist/transport/postmessage.js +78 -0
- package/dist/transport/postmessage.js.map +1 -0
- package/dist/transport/types.d.ts +25 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +11 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/ui/index.d.ts +98 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +32 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +75 -0
- package/src/background/index.ts +152 -0
- package/src/background/register.ts +85 -0
- package/src/dev-reload.ts +60 -0
- package/src/envelope.ts +54 -0
- package/src/globals.ts +62 -0
- package/src/index.ts +171 -0
- package/src/modules/actions.ts +156 -0
- package/src/modules/auth.ts +68 -0
- package/src/modules/base64.ts +87 -0
- package/src/modules/blob.ts +341 -0
- package/src/modules/camera.ts +196 -0
- package/src/modules/cloud.ts +94 -0
- package/src/modules/dashboard.ts +31 -0
- package/src/modules/display.ts +122 -0
- package/src/modules/events.ts +264 -0
- package/src/modules/glasses.ts +44 -0
- package/src/modules/heading.ts +23 -0
- package/src/modules/imu.ts +44 -0
- package/src/modules/input.ts +71 -0
- package/src/modules/led.ts +61 -0
- package/src/modules/location.ts +39 -0
- package/src/modules/mic.ts +74 -0
- package/src/modules/miniapps.ts +90 -0
- package/src/modules/navigation.ts +670 -0
- package/src/modules/permissions.ts +84 -0
- package/src/modules/phone.ts +120 -0
- package/src/modules/pivots/engine.ts +863 -0
- package/src/modules/pivots/geometry.ts +409 -0
- package/src/modules/pivots/instructions.ts +343 -0
- package/src/modules/speaker.ts +328 -0
- package/src/modules/storage.ts +109 -0
- package/src/modules/stream.ts +163 -0
- package/src/modules/system.ts +76 -0
- package/src/modules/transcription.ts +128 -0
- package/src/modules/translation.ts +149 -0
- package/src/modules/ui.ts +498 -0
- package/src/protocol.ts +371 -0
- package/src/react/MentraProvider.tsx +50 -0
- package/src/react/MiniappHeader.tsx +122 -0
- package/src/react/index.ts +12 -0
- package/src/react/useCapabilities.ts +29 -0
- package/src/react/useCapsuleHeaderStyle.ts +54 -0
- package/src/react/useColorScheme.ts +26 -0
- package/src/react/useConnected.ts +47 -0
- package/src/react/useRpc.ts +106 -0
- package/src/react/useSafeArea.ts +40 -0
- package/src/session.ts +878 -0
- package/src/sub-path-types.test-d.ts +49 -0
- package/src/transport/auto.ts +143 -0
- package/src/transport/dispatch.ts +106 -0
- package/src/transport/local-socket.ts +93 -0
- package/src/transport/mock.ts +248 -0
- package/src/transport/postmessage.ts +95 -0
- package/src/transport/types.ts +26 -0
- package/src/ui/index.ts +122 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SystemModule — OS-level utilities (share, open URL, clipboard, download).
|
|
3
|
+
*
|
|
4
|
+
* These bridge to native phone capabilities via LocalMiniappRuntime.
|
|
5
|
+
*/
|
|
6
|
+
import { MiniappRequestType } from "../protocol";
|
|
7
|
+
export class SystemModule {
|
|
8
|
+
constructor(session) {
|
|
9
|
+
this.session = session;
|
|
10
|
+
}
|
|
11
|
+
/** Open the OS share sheet with the given content. */
|
|
12
|
+
async share(options) {
|
|
13
|
+
const result = await this.session.sendRequest({
|
|
14
|
+
type: MiniappRequestType.SHARE,
|
|
15
|
+
...options,
|
|
16
|
+
});
|
|
17
|
+
return result ?? { success: false };
|
|
18
|
+
}
|
|
19
|
+
/** Open a URL in the system browser. Blocks dangerous schemes (javascript:, file:). */
|
|
20
|
+
openUrl(url) {
|
|
21
|
+
this.session.sendOneShot({
|
|
22
|
+
type: MiniappRequestType.OPEN_URL,
|
|
23
|
+
url,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/** Copy text to the system clipboard. */
|
|
27
|
+
async copyToClipboard(text) {
|
|
28
|
+
await this.session.sendRequest({
|
|
29
|
+
type: MiniappRequestType.COPY_CLIPBOARD,
|
|
30
|
+
text,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Download a file. Opens the OS share sheet so user can choose save location. */
|
|
34
|
+
async download(options) {
|
|
35
|
+
const result = await this.session.sendRequest({
|
|
36
|
+
type: MiniappRequestType.DOWNLOAD,
|
|
37
|
+
...options,
|
|
38
|
+
});
|
|
39
|
+
return result ?? { success: false };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=system.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../src/modules/system.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAiChD,MAAM,OAAO,YAAY;IACvB,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAExD,sDAAsD;IACtD,KAAK,CAAC,KAAK,CAAC,OAAqB;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAc;YACzD,IAAI,EAAE,kBAAkB,CAAC,KAAK;YAC9B,GAAG,OAAO;SACX,CAAC,CAAA;QACF,OAAO,MAAM,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IACrC,CAAC;IAED,uFAAuF;IACvF,OAAO,CAAC,GAAW;QACjB,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;YACvB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;YACjC,GAAG;SACJ,CAAC,CAAA;IACJ,CAAC;IAED,yCAAyC;IACzC,KAAK,CAAC,eAAe,CAAC,IAAY;QAChC,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAO;YACnC,IAAI,EAAE,kBAAkB,CAAC,cAAc;YACvC,IAAI;SACL,CAAC,CAAA;IACJ,CAAC;IAED,kFAAkF;IAClF,KAAK,CAAC,QAAQ,CAAC,OAAwB;QACrC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAiB;YAC5D,IAAI,EAAE,kBAAkB,CAAC,QAAQ;YACjC,GAAG,OAAO;SACX,CAAC,CAAA;QACF,OAAO,MAAM,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IACrC,CAAC;CACF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TranscriptionModule — top-level transcription API.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors cloud SDK v3's TranscriptionManager:
|
|
5
|
+
*
|
|
6
|
+
* session.transcription.on(handler) // auto-detect
|
|
7
|
+
* session.transcription.forLanguage("en-US", handler) // single language
|
|
8
|
+
* session.transcription.forLanguage(["en-US", "es-ES"], handler) // multi-language
|
|
9
|
+
* session.transcription.configure({languageHints, vocabulary, diarization})
|
|
10
|
+
* session.transcription.stop() // tear down all
|
|
11
|
+
*
|
|
12
|
+
* Hoisted to top-level (vs. nested under `session.mic`) because transcription
|
|
13
|
+
* is a domain in its own right, not a microphone-input event. The `mic`
|
|
14
|
+
* module still exposes lower-level audio chunks + VAD; this module is for
|
|
15
|
+
* "give me text from speech."
|
|
16
|
+
*
|
|
17
|
+
* MICROPHONE permission must be declared in miniapp.json. The phone runtime
|
|
18
|
+
* rejects with PERMISSION_NOT_DECLARED otherwise.
|
|
19
|
+
*/
|
|
20
|
+
import { MiniappSession } from "../session";
|
|
21
|
+
import type { TranscriptionData, UnsubscribeFn } from "./events";
|
|
22
|
+
/** Configuration for cloud-side transcription behavior. */
|
|
23
|
+
export interface TranscriptionConfig {
|
|
24
|
+
/** ISO 639-1 language hints to improve detection accuracy (e.g. ["en", "ja"]). */
|
|
25
|
+
languageHints?: string[];
|
|
26
|
+
/** Custom vocabulary / boosted terms (e.g. ["MentraOS", "HIPAA"]). */
|
|
27
|
+
vocabulary?: string[];
|
|
28
|
+
/** Enable speaker diarisation. Defaults vary by provider. */
|
|
29
|
+
diarization?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare class TranscriptionModule {
|
|
32
|
+
private readonly session;
|
|
33
|
+
private readonly unsubs;
|
|
34
|
+
private currentConfig;
|
|
35
|
+
constructor(session: MiniappSession);
|
|
36
|
+
/**
|
|
37
|
+
* Subscribe to all transcription events (auto-detect language). The
|
|
38
|
+
* detected language is in `data.language`.
|
|
39
|
+
*
|
|
40
|
+
* Wire-level: subscribes to `transcription:auto`. Today's wildcard fan-out
|
|
41
|
+
* (handlers on `transcription:auto` receive any `transcription:<lang>`
|
|
42
|
+
* event) preserves existing semantics.
|
|
43
|
+
*/
|
|
44
|
+
on(handler: (data: TranscriptionData) => void): UnsubscribeFn;
|
|
45
|
+
/**
|
|
46
|
+
* Subscribe to transcription for one or more specific languages. Each call
|
|
47
|
+
* is independent; multiple can be active simultaneously.
|
|
48
|
+
*
|
|
49
|
+
* @param language - BCP-47 tag(s), e.g. `"en-US"` or `["en-US", "es-ES"]`.
|
|
50
|
+
* @param handler - Called for every event in any of the listed languages.
|
|
51
|
+
*/
|
|
52
|
+
forLanguage(language: string | string[], handler: (data: TranscriptionData) => void): UnsubscribeFn;
|
|
53
|
+
/**
|
|
54
|
+
* Apply transcription configuration (language hints, custom vocabulary,
|
|
55
|
+
* diarisation toggle). Sent to the cloud immediately. Cached locally so we
|
|
56
|
+
* could re-send on reconnect (future).
|
|
57
|
+
*/
|
|
58
|
+
configure(config: TranscriptionConfig): void;
|
|
59
|
+
/** Tear down every transcription subscription this module owns. */
|
|
60
|
+
stop(): void;
|
|
61
|
+
/** True iff `MICROPHONE` is declared in the miniapp's manifest. */
|
|
62
|
+
get hasPermission(): boolean;
|
|
63
|
+
/** @internal — current config, read by tests / future reconnect logic. */
|
|
64
|
+
_getConfig(): TranscriptionConfig | null;
|
|
65
|
+
private track;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=transcription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcription.d.ts","sourceRoot":"","sources":["../../src/modules/transcription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAAC,iBAAiB,EAAE,aAAa,EAAC,MAAM,UAAU,CAAA;AAE9D,2DAA2D;AAC3D,MAAM,WAAW,mBAAmB;IAClC,kFAAkF;IAClF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,qBAAa,mBAAmB;IAIlB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;IAClD,OAAO,CAAC,aAAa,CAAmC;gBAE3B,OAAO,EAAE,cAAc;IAEpD;;;;;;;OAOG;IACH,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,GAAG,aAAa;IAM7D;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,GAAG,aAAa;IAsBnG;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAQ5C,mEAAmE;IACnE,IAAI,IAAI,IAAI;IAWZ,mEAAmE;IACnE,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,0EAA0E;IAC1E,UAAU,IAAI,mBAAmB,GAAG,IAAI;IAMxC,OAAO,CAAC,KAAK;CAOd"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TranscriptionModule — top-level transcription API.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors cloud SDK v3's TranscriptionManager:
|
|
5
|
+
*
|
|
6
|
+
* session.transcription.on(handler) // auto-detect
|
|
7
|
+
* session.transcription.forLanguage("en-US", handler) // single language
|
|
8
|
+
* session.transcription.forLanguage(["en-US", "es-ES"], handler) // multi-language
|
|
9
|
+
* session.transcription.configure({languageHints, vocabulary, diarization})
|
|
10
|
+
* session.transcription.stop() // tear down all
|
|
11
|
+
*
|
|
12
|
+
* Hoisted to top-level (vs. nested under `session.mic`) because transcription
|
|
13
|
+
* is a domain in its own right, not a microphone-input event. The `mic`
|
|
14
|
+
* module still exposes lower-level audio chunks + VAD; this module is for
|
|
15
|
+
* "give me text from speech."
|
|
16
|
+
*
|
|
17
|
+
* MICROPHONE permission must be declared in miniapp.json. The phone runtime
|
|
18
|
+
* rejects with PERMISSION_NOT_DECLARED otherwise.
|
|
19
|
+
*/
|
|
20
|
+
import { MiniappRequestType, MiniappStreamType } from "../protocol";
|
|
21
|
+
export class TranscriptionModule {
|
|
22
|
+
constructor(session) {
|
|
23
|
+
this.session = session;
|
|
24
|
+
this.unsubs = new Set();
|
|
25
|
+
this.currentConfig = null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Subscribe to all transcription events (auto-detect language). The
|
|
29
|
+
* detected language is in `data.language`.
|
|
30
|
+
*
|
|
31
|
+
* Wire-level: subscribes to `transcription:auto`. Today's wildcard fan-out
|
|
32
|
+
* (handlers on `transcription:auto` receive any `transcription:<lang>`
|
|
33
|
+
* event) preserves existing semantics.
|
|
34
|
+
*/
|
|
35
|
+
on(handler) {
|
|
36
|
+
return this.track(this.session._subscribe(`${MiniappStreamType.TRANSCRIPTION}:auto`, handler));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Subscribe to transcription for one or more specific languages. Each call
|
|
40
|
+
* is independent; multiple can be active simultaneously.
|
|
41
|
+
*
|
|
42
|
+
* @param language - BCP-47 tag(s), e.g. `"en-US"` or `["en-US", "es-ES"]`.
|
|
43
|
+
* @param handler - Called for every event in any of the listed languages.
|
|
44
|
+
*/
|
|
45
|
+
forLanguage(language, handler) {
|
|
46
|
+
const langs = Array.isArray(language) ? language : [language];
|
|
47
|
+
if (langs.length === 0)
|
|
48
|
+
return () => { };
|
|
49
|
+
const unsubs = [];
|
|
50
|
+
for (const lang of langs) {
|
|
51
|
+
unsubs.push(this.session._subscribe(`${MiniappStreamType.TRANSCRIPTION}:${lang}`, handler));
|
|
52
|
+
}
|
|
53
|
+
const combined = () => {
|
|
54
|
+
for (const u of unsubs) {
|
|
55
|
+
try {
|
|
56
|
+
u();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
/* ignore */
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
return this.track(combined);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Apply transcription configuration (language hints, custom vocabulary,
|
|
67
|
+
* diarisation toggle). Sent to the cloud immediately. Cached locally so we
|
|
68
|
+
* could re-send on reconnect (future).
|
|
69
|
+
*/
|
|
70
|
+
configure(config) {
|
|
71
|
+
this.currentConfig = { ...config };
|
|
72
|
+
this.session.sendOneShot({
|
|
73
|
+
type: MiniappRequestType.TRANSCRIPTION_CONFIG,
|
|
74
|
+
config: { ...config },
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/** Tear down every transcription subscription this module owns. */
|
|
78
|
+
stop() {
|
|
79
|
+
for (const u of this.unsubs) {
|
|
80
|
+
try {
|
|
81
|
+
u();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
/* ignore */
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
this.unsubs.clear();
|
|
88
|
+
}
|
|
89
|
+
/** True iff `MICROPHONE` is declared in the miniapp's manifest. */
|
|
90
|
+
get hasPermission() {
|
|
91
|
+
return this.session._hasManifestPermission("MICROPHONE");
|
|
92
|
+
}
|
|
93
|
+
/** @internal — current config, read by tests / future reconnect logic. */
|
|
94
|
+
_getConfig() {
|
|
95
|
+
return this.currentConfig ? { ...this.currentConfig } : null;
|
|
96
|
+
}
|
|
97
|
+
// ------------------------------------------------------------------------
|
|
98
|
+
track(unsub) {
|
|
99
|
+
this.unsubs.add(unsub);
|
|
100
|
+
return () => {
|
|
101
|
+
this.unsubs.delete(unsub);
|
|
102
|
+
unsub();
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=transcription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcription.js","sourceRoot":"","sources":["../../src/modules/transcription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAC,kBAAkB,EAAE,iBAAiB,EAAC,MAAM,aAAa,CAAA;AAcjE,MAAM,OAAO,mBAAmB;IAI9B,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;QAHnC,WAAM,GAAG,IAAI,GAAG,EAAiB,CAAA;QAC1C,kBAAa,GAA+B,IAAI,CAAA;IAED,CAAC;IAExD;;;;;;;OAOG;IACH,EAAE,CAAC,OAA0C;QAC3C,OAAO,IAAI,CAAC,KAAK,CACf,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,iBAAiB,CAAC,aAAa,OAAO,EAAE,OAAkC,CAAC,CACvG,CAAA;IACH,CAAC;IAED;;;;;;OAMG;IACH,WAAW,CAAC,QAA2B,EAAE,OAA0C;QACjF,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;QAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAA;QAEvC,MAAM,MAAM,GAAoB,EAAE,CAAA;QAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,iBAAiB,CAAC,aAAa,IAAI,IAAI,EAAE,EAAE,OAAkC,CAAC,CAC1G,CAAA;QACH,CAAC;QACD,MAAM,QAAQ,GAAkB,GAAG,EAAE;YACnC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,CAAC,EAAE,CAAA;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,YAAY;gBACd,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC7B,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,MAA2B;QACnC,IAAI,CAAC,aAAa,GAAG,EAAC,GAAG,MAAM,EAAC,CAAA;QAChC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;YACvB,IAAI,EAAE,kBAAkB,CAAC,oBAAoB;YAC7C,MAAM,EAAE,EAAC,GAAG,MAAM,EAAC;SACpB,CAAC,CAAA;IACJ,CAAC;IAED,mEAAmE;IACnE,IAAI;QACF,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,CAAC,EAAE,CAAA;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,mEAAmE;IACnE,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAA;IAC1D,CAAC;IAED,0EAA0E;IAC1E,UAAU;QACR,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAC,GAAG,IAAI,CAAC,aAAa,EAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5D,CAAC;IAED,2EAA2E;IAEnE,KAAK,CAAC,KAAoB;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACtB,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACzB,KAAK,EAAE,CAAA;QACT,CAAC,CAAA;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TranslationModule — top-level translation API.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors cloud SDK v3's TranslationManager surface:
|
|
5
|
+
*
|
|
6
|
+
* session.translation.on(handler) // any pair
|
|
7
|
+
* session.translation.to(target, handler) // any-source → target
|
|
8
|
+
* session.translation.to([targets], handler) // any-source → many
|
|
9
|
+
* session.translation.fromTo(source, target, handler) // specific pair
|
|
10
|
+
* session.translation.fromTo(source, [targets], handler) // source → many
|
|
11
|
+
* session.translation.stop() // tear down all
|
|
12
|
+
*
|
|
13
|
+
* Internally each subscribe registers against a `translation:<source>:<target>`
|
|
14
|
+
* stream pattern; LocalMiniappRuntime's wildcard matcher routes incoming
|
|
15
|
+
* `translation:<src>:<dst>` events to any matching `*` patterns.
|
|
16
|
+
*
|
|
17
|
+
* MICROPHONE permission required.
|
|
18
|
+
*/
|
|
19
|
+
import { MiniappSession } from "../session";
|
|
20
|
+
import type { TranslationData, UnsubscribeFn } from "./events";
|
|
21
|
+
export type TranslationHandler = (data: TranslationData) => void;
|
|
22
|
+
export declare class TranslationModule {
|
|
23
|
+
private readonly session;
|
|
24
|
+
private readonly unsubs;
|
|
25
|
+
constructor(session: MiniappSession);
|
|
26
|
+
/**
|
|
27
|
+
* Subscribe to every translation event from the cloud, regardless of
|
|
28
|
+
* source or target language.
|
|
29
|
+
*
|
|
30
|
+
* Uses the wildcard stream `translation:*:*` — cheap to register on the
|
|
31
|
+
* client, expensive on the cloud side (cloud fans every active pair out
|
|
32
|
+
* to this subscriber). Prefer `to` or `fromTo` when you know the
|
|
33
|
+
* language(s) you care about.
|
|
34
|
+
*/
|
|
35
|
+
on(handler: TranslationHandler): UnsubscribeFn;
|
|
36
|
+
/**
|
|
37
|
+
* Subscribe to any translation that lands at the given target language(s),
|
|
38
|
+
* regardless of source. Useful for "I'm a Spanish speaker, translate
|
|
39
|
+
* whatever I hear to Spanish."
|
|
40
|
+
*/
|
|
41
|
+
to(target: string | string[], handler: TranslationHandler): UnsubscribeFn;
|
|
42
|
+
/**
|
|
43
|
+
* Subscribe to a specific source → target translation pair. Pass an
|
|
44
|
+
* array for `target` to fan a single handler across multiple targets
|
|
45
|
+
* from the same source.
|
|
46
|
+
*/
|
|
47
|
+
fromTo(source: string, target: string | string[], handler: TranslationHandler): UnsubscribeFn;
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated Renamed to `fromTo(source, target, handler)` for cloud
|
|
50
|
+
* SDK v3 parity. This alias will be removed in a future release.
|
|
51
|
+
*/
|
|
52
|
+
forLanguagePair(fromLang: string, toLang: string, handler: TranslationHandler): UnsubscribeFn;
|
|
53
|
+
/** Tear down every translation subscription this module owns. */
|
|
54
|
+
stop(): void;
|
|
55
|
+
/** True iff `MICROPHONE` is declared in the miniapp's manifest. */
|
|
56
|
+
get hasPermission(): boolean;
|
|
57
|
+
private track;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=translation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translation.d.ts","sourceRoot":"","sources":["../../src/modules/translation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAC,cAAc,EAAC,MAAM,YAAY,CAAA;AACzC,OAAO,KAAK,EAAC,eAAe,EAAE,aAAa,EAAC,MAAM,UAAU,CAAA;AAE5D,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;AAEhE,qBAAa,iBAAiB;IAGhB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2B;gBAErB,OAAO,EAAE,cAAc;IAEpD;;;;;;;;OAQG;IACH,EAAE,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAS9C;;;;OAIG;IACH,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAwBzE;;;;OAIG;IACH,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,OAAO,EAAE,kBAAkB,GAC1B,aAAa;IAwBhB;;;OAGG;IACH,eAAe,CACb,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB,GAC1B,aAAa;IAIhB,iEAAiE;IACjE,IAAI,IAAI,IAAI;IAWZ,mEAAmE;IACnE,IAAI,aAAa,IAAI,OAAO,CAE3B;IAID,OAAO,CAAC,KAAK;CAOd"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview TranslationModule — top-level translation API.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors cloud SDK v3's TranslationManager surface:
|
|
5
|
+
*
|
|
6
|
+
* session.translation.on(handler) // any pair
|
|
7
|
+
* session.translation.to(target, handler) // any-source → target
|
|
8
|
+
* session.translation.to([targets], handler) // any-source → many
|
|
9
|
+
* session.translation.fromTo(source, target, handler) // specific pair
|
|
10
|
+
* session.translation.fromTo(source, [targets], handler) // source → many
|
|
11
|
+
* session.translation.stop() // tear down all
|
|
12
|
+
*
|
|
13
|
+
* Internally each subscribe registers against a `translation:<source>:<target>`
|
|
14
|
+
* stream pattern; LocalMiniappRuntime's wildcard matcher routes incoming
|
|
15
|
+
* `translation:<src>:<dst>` events to any matching `*` patterns.
|
|
16
|
+
*
|
|
17
|
+
* MICROPHONE permission required.
|
|
18
|
+
*/
|
|
19
|
+
import { MiniappStreamType } from "../protocol";
|
|
20
|
+
export class TranslationModule {
|
|
21
|
+
constructor(session) {
|
|
22
|
+
this.session = session;
|
|
23
|
+
this.unsubs = new Set();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Subscribe to every translation event from the cloud, regardless of
|
|
27
|
+
* source or target language.
|
|
28
|
+
*
|
|
29
|
+
* Uses the wildcard stream `translation:*:*` — cheap to register on the
|
|
30
|
+
* client, expensive on the cloud side (cloud fans every active pair out
|
|
31
|
+
* to this subscriber). Prefer `to` or `fromTo` when you know the
|
|
32
|
+
* language(s) you care about.
|
|
33
|
+
*/
|
|
34
|
+
on(handler) {
|
|
35
|
+
return this.track(this.session._subscribe(`${MiniappStreamType.TRANSLATION}:*:*`, handler));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Subscribe to any translation that lands at the given target language(s),
|
|
39
|
+
* regardless of source. Useful for "I'm a Spanish speaker, translate
|
|
40
|
+
* whatever I hear to Spanish."
|
|
41
|
+
*/
|
|
42
|
+
to(target, handler) {
|
|
43
|
+
const targets = Array.isArray(target) ? target : [target];
|
|
44
|
+
if (targets.length === 0)
|
|
45
|
+
return () => { };
|
|
46
|
+
const unsubs = [];
|
|
47
|
+
for (const t of targets) {
|
|
48
|
+
unsubs.push(this.session._subscribe(`${MiniappStreamType.TRANSLATION}:*:${t}`, handler));
|
|
49
|
+
}
|
|
50
|
+
const composite = () => {
|
|
51
|
+
for (const u of unsubs) {
|
|
52
|
+
try {
|
|
53
|
+
u();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
/* ignore */
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
return this.track(composite);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Subscribe to a specific source → target translation pair. Pass an
|
|
64
|
+
* array for `target` to fan a single handler across multiple targets
|
|
65
|
+
* from the same source.
|
|
66
|
+
*/
|
|
67
|
+
fromTo(source, target, handler) {
|
|
68
|
+
const targets = Array.isArray(target) ? target : [target];
|
|
69
|
+
if (targets.length === 0)
|
|
70
|
+
return () => { };
|
|
71
|
+
const unsubs = [];
|
|
72
|
+
for (const t of targets) {
|
|
73
|
+
unsubs.push(this.session._subscribe(`${MiniappStreamType.TRANSLATION}:${source}:${t}`, handler));
|
|
74
|
+
}
|
|
75
|
+
const composite = () => {
|
|
76
|
+
for (const u of unsubs) {
|
|
77
|
+
try {
|
|
78
|
+
u();
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* ignore */
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return this.track(composite);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* @deprecated Renamed to `fromTo(source, target, handler)` for cloud
|
|
89
|
+
* SDK v3 parity. This alias will be removed in a future release.
|
|
90
|
+
*/
|
|
91
|
+
forLanguagePair(fromLang, toLang, handler) {
|
|
92
|
+
return this.fromTo(fromLang, toLang, handler);
|
|
93
|
+
}
|
|
94
|
+
/** Tear down every translation subscription this module owns. */
|
|
95
|
+
stop() {
|
|
96
|
+
for (const u of this.unsubs) {
|
|
97
|
+
try {
|
|
98
|
+
u();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
/* ignore */
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
this.unsubs.clear();
|
|
105
|
+
}
|
|
106
|
+
/** True iff `MICROPHONE` is declared in the miniapp's manifest. */
|
|
107
|
+
get hasPermission() {
|
|
108
|
+
return this.session._hasManifestPermission("MICROPHONE");
|
|
109
|
+
}
|
|
110
|
+
// ------------------------------------------------------------------------
|
|
111
|
+
track(unsub) {
|
|
112
|
+
this.unsubs.add(unsub);
|
|
113
|
+
return () => {
|
|
114
|
+
this.unsubs.delete(unsub);
|
|
115
|
+
unsub();
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=translation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translation.js","sourceRoot":"","sources":["../../src/modules/translation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* session.ui — bus between a background JSContext miniapp and its
|
|
3
|
+
* on-demand UI WebView. Supports two interaction patterns:
|
|
4
|
+
*
|
|
5
|
+
* 1. **Broadcast** (fire-and-forget, either direction)
|
|
6
|
+
* - background → UI: `session.ui.send(channel, payload)`
|
|
7
|
+
* - UI → background: `mentra.send(channel, payload)`
|
|
8
|
+
* - subscribe: `session.ui.on(channel, cb)` / `mentra.on(channel, cb)`
|
|
9
|
+
*
|
|
10
|
+
* 2. **RPC** (request/response, UI → background only)
|
|
11
|
+
* - UI side: `await mentra.request(channel, payload, options?)`
|
|
12
|
+
* - background side: `session.ui.handle(channel, (payload, ctx?) => result)`
|
|
13
|
+
* - single handler per channel; double-register throws synchronously.
|
|
14
|
+
* - errors thrown in the handler reject the caller's promise.
|
|
15
|
+
* - cancellation via `options.signal` aborts the handler's `ctx.signal`
|
|
16
|
+
* and drops the eventual reply.
|
|
17
|
+
*
|
|
18
|
+
* Broadcast vs. RPC is declared at the channel level: wrap a channel's
|
|
19
|
+
* payload type in `Rpc<Req, Res>` in the shared registry to make it RPC.
|
|
20
|
+
* Wrong-API-for-channel is a compile-time error.
|
|
21
|
+
*
|
|
22
|
+
* Buffering:
|
|
23
|
+
* - `mentra.send` BUFFERS until `mentra.ready()` acks. The WebView is
|
|
24
|
+
* the short-lived side and shouldn't drop user input.
|
|
25
|
+
* - `session.ui.send` silently DROPS when no WebView is bound.
|
|
26
|
+
* Background is the source of truth; UI state shouldn't accumulate.
|
|
27
|
+
* - Per-channel inbound buffering (up to 32 payloads) covers the
|
|
28
|
+
* `controller pushed before React attached the listener` race — see
|
|
29
|
+
* the WebView shim for details.
|
|
30
|
+
*
|
|
31
|
+
* Wire envelopes (internal — not part of the SDK surface):
|
|
32
|
+
* - `UI_OPEN` — WebView posted `{type:"ready"}`.
|
|
33
|
+
* - `UI_CLOSE` — host tore down the WebView.
|
|
34
|
+
* - `UI_MESSAGE` — WebView → background. `requestId` set on RPC calls.
|
|
35
|
+
* - `UI_SEND` — background → WebView. `requestId` set on RPC replies.
|
|
36
|
+
* - `UI_CANCEL` — either direction. Carries only `requestId`; aborts
|
|
37
|
+
* the in-flight handler's signal.
|
|
38
|
+
*/
|
|
39
|
+
import type { MiniappSession } from "../session";
|
|
40
|
+
export type UIChannelHandler<T = unknown> = (payload: T) => void;
|
|
41
|
+
export type UIUnsubscribe = () => void;
|
|
42
|
+
/**
|
|
43
|
+
* Brand for declaring an RPC channel in the shared Channels registry.
|
|
44
|
+
*
|
|
45
|
+
* Wrap a channel's payload type in `Rpc<Req, Res>` to mark it as
|
|
46
|
+
* request/response. The SDK's `mentra.request` / `session.ui.handle`
|
|
47
|
+
* accept only `Rpc<...>` channels; `mentra.send` / `session.ui.on`
|
|
48
|
+
* accept only non-RPC channels. Using the wrong API for the wrong
|
|
49
|
+
* channel is a compile-time error.
|
|
50
|
+
*
|
|
51
|
+
* export interface Channels {
|
|
52
|
+
* "live-transcript": {text: string} // broadcast
|
|
53
|
+
* "compute-route": Rpc<RouteOpts, RouteResult> // RPC
|
|
54
|
+
* }
|
|
55
|
+
*/
|
|
56
|
+
declare const __rpc_brand: unique symbol;
|
|
57
|
+
export type Rpc<Req, Res> = {
|
|
58
|
+
readonly [__rpc_brand]: true;
|
|
59
|
+
readonly req: Req;
|
|
60
|
+
readonly res: Res;
|
|
61
|
+
};
|
|
62
|
+
/** True if `T` is an `Rpc<...>` channel entry. */
|
|
63
|
+
export type IsRpc<T> = T extends Rpc<unknown, unknown> ? true : false;
|
|
64
|
+
/** Request payload type of an `Rpc<Req, Res>` entry. */
|
|
65
|
+
export type RpcReq<T> = T extends Rpc<infer Req, unknown> ? Req : never;
|
|
66
|
+
/** Response payload type of an `Rpc<Req, Res>` entry. */
|
|
67
|
+
export type RpcRes<T> = T extends Rpc<unknown, infer Res> ? Res : never;
|
|
68
|
+
/** Options accepted by `mentra.request`. */
|
|
69
|
+
export interface RpcRequestOptions {
|
|
70
|
+
/** Abort the in-flight call. Sends UI_CANCEL to the handler. */
|
|
71
|
+
signal?: AbortSignal;
|
|
72
|
+
/** Reject with `MentraRpcTimeoutError` after this many ms. No default. */
|
|
73
|
+
timeout?: number;
|
|
74
|
+
}
|
|
75
|
+
/** Context passed as the optional 2nd arg to an `ui.handle` handler. */
|
|
76
|
+
export interface RpcHandlerContext {
|
|
77
|
+
/** Aborts when the UI side cancels the call (or its timeout fires). */
|
|
78
|
+
signal: AbortSignal;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Error thrown by `mentra.request` when the handler threw or returned an
|
|
82
|
+
* error envelope. Plain `Error` subclass — distinguished by `err.name`.
|
|
83
|
+
* `err.cause` is `{code?: string}` if the handler attached one.
|
|
84
|
+
*/
|
|
85
|
+
export declare class MentraRpcError extends Error {
|
|
86
|
+
constructor(message: string, options?: {
|
|
87
|
+
cause?: {
|
|
88
|
+
code?: string;
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Thrown by `mentra.request` when its `{timeout}` elapses. */
|
|
93
|
+
export declare class MentraRpcTimeoutError extends Error {
|
|
94
|
+
constructor(message?: string);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Public surface mirrored on `session.ui`. Generic over a `Channels`
|
|
98
|
+
* type-map so miniapps importing the typed `shared/channels.ts` get
|
|
99
|
+
* compile-time enforcement on channel names + payload shapes.
|
|
100
|
+
*
|
|
101
|
+
* Broadcast vs. RPC channels are distinguished at the type level:
|
|
102
|
+
* - Channel value `Rpc<Req, Res>` → only `handle()` accepts it on
|
|
103
|
+
* background; only `mentra.request(...)` accepts it on UI.
|
|
104
|
+
* - Channel value anything else → only `send()`/`on()` accept it
|
|
105
|
+
* on both sides.
|
|
106
|
+
*
|
|
107
|
+
* The default `Record<string, unknown>` mapping lets unannotated usage
|
|
108
|
+
* compile — the SDK doesn't impose a registry of its own.
|
|
109
|
+
*/
|
|
110
|
+
export interface UIModule<TChannels extends object = Record<string, unknown>> {
|
|
111
|
+
/** True iff a WebView is currently bound to this miniapp. */
|
|
112
|
+
isOpen(): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Subscribe to the "WebView mounted + ready()" lifecycle event. If
|
|
115
|
+
* a WebView is already mounted when subscribe() is called, the
|
|
116
|
+
* handler fires immediately for the current binding.
|
|
117
|
+
*/
|
|
118
|
+
onOpen(cb: () => void): UIUnsubscribe;
|
|
119
|
+
/**
|
|
120
|
+
* Subscribe to the "WebView unmounted" lifecycle event. Fires once
|
|
121
|
+
* per close; if no WebView is bound at subscribe time the handler
|
|
122
|
+
* stays armed for the next mount → close cycle.
|
|
123
|
+
*/
|
|
124
|
+
onClose(cb: () => void): UIUnsubscribe;
|
|
125
|
+
/**
|
|
126
|
+
* Broadcast a typed message to the bound WebView. Silently drops if
|
|
127
|
+
* no WebView is bound. Compile-error if `C` is an RPC channel.
|
|
128
|
+
*/
|
|
129
|
+
send<C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? never : C, payload: TChannels[C]): void;
|
|
130
|
+
/**
|
|
131
|
+
* Subscribe to broadcast messages from the bound WebView. Returns an
|
|
132
|
+
* unsubscribe fn. Compile-error if `C` is an RPC channel — use
|
|
133
|
+
* `handle()` for RPC channels.
|
|
134
|
+
*/
|
|
135
|
+
on<C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? never : C, cb: UIChannelHandler<TChannels[C]>): UIUnsubscribe;
|
|
136
|
+
/**
|
|
137
|
+
* Register the single handler for an RPC channel. The UI side calls
|
|
138
|
+
* `mentra.request(channel, payload, options?)`; this handler resolves
|
|
139
|
+
* the call.
|
|
140
|
+
*
|
|
141
|
+
* Throws synchronously if a handler is already registered for the
|
|
142
|
+
* channel. Returns a deregister fn that removes the handler.
|
|
143
|
+
*
|
|
144
|
+
* Compile-error if `C` is a broadcast (non-Rpc) channel.
|
|
145
|
+
*/
|
|
146
|
+
handle<C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? C : never, handler: (payload: RpcReq<TChannels[C]>, ctx?: RpcHandlerContext) => Promise<RpcRes<TChannels[C]>> | RpcRes<TChannels[C]>): UIUnsubscribe;
|
|
147
|
+
}
|
|
148
|
+
export interface RpcErrorEnvelope {
|
|
149
|
+
message: string;
|
|
150
|
+
code?: string;
|
|
151
|
+
stage?: string;
|
|
152
|
+
transport?: string;
|
|
153
|
+
}
|
|
154
|
+
export declare class UIModuleImpl<TChannels extends object = Record<string, unknown>> implements UIModule<TChannels> {
|
|
155
|
+
private readonly session;
|
|
156
|
+
/** True between UI_OPEN and the matching UI_CLOSE. */
|
|
157
|
+
private bound;
|
|
158
|
+
/** Monotonic outbound seq number. Reset on bind. */
|
|
159
|
+
private nextSeq;
|
|
160
|
+
/** Open-lifecycle handlers — fire on every UI_OPEN. */
|
|
161
|
+
private readonly openHandlers;
|
|
162
|
+
private readonly closeHandlers;
|
|
163
|
+
/** channel → set of subscribers. */
|
|
164
|
+
private readonly channelHandlers;
|
|
165
|
+
/** channel → single registered RPC handler. */
|
|
166
|
+
private readonly rpcHandlers;
|
|
167
|
+
/** requestId → AbortController for in-flight RPC handler invocations. */
|
|
168
|
+
private readonly inflightRpc;
|
|
169
|
+
constructor(session: MiniappSession);
|
|
170
|
+
isOpen: () => boolean;
|
|
171
|
+
onOpen: (cb: () => void) => UIUnsubscribe;
|
|
172
|
+
onClose: (cb: () => void) => UIUnsubscribe;
|
|
173
|
+
send: <C extends keyof TChannels & string>(channel: C, payload: TChannels[C]) => void;
|
|
174
|
+
on: <C extends keyof TChannels & string>(channel: C, cb: UIChannelHandler<TChannels[C]>) => UIUnsubscribe;
|
|
175
|
+
handle: <C extends keyof TChannels & string>(channel: IsRpc<TChannels[C]> extends true ? C : never, handler: (payload: RpcReq<TChannels[C]>, ctx?: RpcHandlerContext) => Promise<RpcRes<TChannels[C]>> | RpcRes<TChannels[C]>) => UIUnsubscribe;
|
|
176
|
+
/** Fire every registered open handler once. Guarded per-handler. */
|
|
177
|
+
private fireOpenHandlers;
|
|
178
|
+
/** @internal — handle UI_OPEN / UI_CLOSE / UI_MESSAGE envelopes from the host. */
|
|
179
|
+
private handleInbound;
|
|
180
|
+
/** @internal — invoke a registered RPC handler and send back the reply. */
|
|
181
|
+
private dispatchRpcCall;
|
|
182
|
+
/** @internal — send a UI_SEND envelope tagged with a requestId. */
|
|
183
|
+
private sendRpcReply;
|
|
184
|
+
}
|
|
185
|
+
export {};
|
|
186
|
+
//# sourceMappingURL=ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../src/modules/ui.ts"],"names":[],"mappings":"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"}
|