@glassly/miniapp 0.3.0-dev.2 → 0.3.0-dev.462
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 +219 -74
- package/dist/background/index.d.ts +14 -8
- package/dist/background/index.d.ts.map +1 -1
- package/dist/background/index.js +4 -0
- package/dist/background/index.js.map +1 -1
- package/dist/background/register.d.ts +1 -1
- package/dist/background/register.js +1 -1
- package/dist/display/index.d.ts +23 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.js +17 -0
- package/dist/display/index.js.map +1 -0
- package/dist/display/measurer/TextMeasurer.d.ts +160 -0
- package/dist/display/measurer/TextMeasurer.d.ts.map +1 -0
- package/dist/display/measurer/TextMeasurer.js +272 -0
- package/dist/display/measurer/TextMeasurer.js.map +1 -0
- package/dist/display/measurer/index.d.ts +10 -0
- package/dist/display/measurer/index.d.ts.map +1 -0
- package/dist/display/measurer/index.js +11 -0
- package/dist/display/measurer/index.js.map +1 -0
- package/dist/display/measurer/script-detection.d.ts +53 -0
- package/dist/display/measurer/script-detection.d.ts.map +1 -0
- package/dist/display/measurer/script-detection.js +184 -0
- package/dist/display/measurer/script-detection.js.map +1 -0
- package/dist/display/pixelArt.d.ts +22 -0
- package/dist/display/pixelArt.d.ts.map +1 -0
- package/dist/display/pixelArt.js +126 -0
- package/dist/display/pixelArt.js.map +1 -0
- package/dist/display/profiles/g1.d.ts +33 -0
- package/dist/display/profiles/g1.d.ts.map +1 -0
- package/dist/display/profiles/g1.js +214 -0
- package/dist/display/profiles/g1.js.map +1 -0
- package/dist/display/profiles/g2.d.ts +13 -0
- package/dist/display/profiles/g2.d.ts.map +1 -0
- package/dist/display/profiles/g2.js +34 -0
- package/dist/display/profiles/g2.js.map +1 -0
- package/dist/display/profiles/index.d.ts +12 -0
- package/dist/display/profiles/index.d.ts.map +1 -0
- package/dist/display/profiles/index.js +15 -0
- package/dist/display/profiles/index.js.map +1 -0
- package/dist/display/profiles/nex.d.ts +10 -0
- package/dist/display/profiles/nex.d.ts.map +1 -0
- package/dist/display/profiles/nex.js +150 -0
- package/dist/display/profiles/nex.js.map +1 -0
- package/dist/display/profiles/types.d.ts +103 -0
- package/dist/display/profiles/types.d.ts.map +1 -0
- package/dist/display/profiles/types.js +2 -0
- package/dist/display/profiles/types.js.map +1 -0
- package/dist/display/profiles/z100.d.ts +33 -0
- package/dist/display/profiles/z100.d.ts.map +1 -0
- package/dist/display/profiles/z100.js +182 -0
- package/dist/display/profiles/z100.js.map +1 -0
- package/dist/display/scene/types.d.ts +292 -0
- package/dist/display/scene/types.d.ts.map +1 -0
- package/dist/display/scene/types.js +0 -0
- package/dist/display/scene/types.js.map +1 -0
- package/dist/display/wrapper/TextWrapper.d.ts +102 -0
- package/dist/display/wrapper/TextWrapper.d.ts.map +1 -0
- package/dist/display/wrapper/TextWrapper.js +469 -0
- package/dist/display/wrapper/TextWrapper.js.map +1 -0
- package/dist/display/wrapper/index.d.ts +12 -0
- package/dist/display/wrapper/index.d.ts.map +1 -0
- package/dist/display/wrapper/index.js +12 -0
- package/dist/display/wrapper/index.js.map +1 -0
- package/dist/display/wrapper/types.d.ts +75 -0
- package/dist/display/wrapper/types.d.ts.map +1 -0
- package/dist/display/wrapper/types.js +11 -0
- package/dist/display/wrapper/types.js.map +1 -0
- package/dist/globals.d.ts +5 -5
- package/dist/globals.d.ts.map +1 -1
- package/dist/globals.js +1 -1
- package/dist/globals.js.map +1 -1
- package/dist/hardware.d.ts +4 -18
- package/dist/hardware.d.ts.map +1 -1
- package/dist/hardware.js +2 -13
- package/dist/hardware.js.map +1 -1
- package/dist/index.d.ts +16 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/knownApps.d.ts +26 -0
- package/dist/knownApps.d.ts.map +1 -0
- package/dist/knownApps.js +140 -0
- package/dist/knownApps.js.map +1 -0
- package/dist/mirror/canvas.d.ts +22 -0
- package/dist/mirror/canvas.d.ts.map +1 -0
- package/dist/mirror/canvas.js +311 -0
- package/dist/mirror/canvas.js.map +1 -0
- package/dist/mirror/geometry.d.ts +69 -0
- package/dist/mirror/geometry.d.ts.map +1 -0
- package/dist/mirror/geometry.js +75 -0
- package/dist/mirror/geometry.js.map +1 -0
- package/dist/mirror/index.d.ts +3 -0
- package/dist/mirror/index.d.ts.map +1 -0
- package/dist/mirror/index.js +2 -0
- package/dist/mirror/index.js.map +1 -0
- package/dist/mirror/types.d.ts +40 -0
- package/dist/mirror/types.d.ts.map +1 -0
- package/dist/mirror/types.js +2 -0
- package/dist/mirror/types.js.map +1 -0
- package/dist/modules/auth.d.ts +1 -1
- package/dist/modules/auth.d.ts.map +1 -1
- package/dist/modules/auth.js +2 -2
- package/dist/modules/auth.js.map +1 -1
- package/dist/modules/compass.d.ts +47 -0
- package/dist/modules/compass.d.ts.map +1 -0
- package/dist/modules/compass.js +39 -0
- package/dist/modules/compass.js.map +1 -0
- package/dist/modules/display.d.ts +192 -8
- package/dist/modules/display.d.ts.map +1 -1
- package/dist/modules/display.js +40 -3
- package/dist/modules/display.js.map +1 -1
- package/dist/modules/events.d.ts +30 -2
- package/dist/modules/events.d.ts.map +1 -1
- package/dist/modules/events.js.map +1 -1
- package/dist/modules/input.d.ts +40 -1
- package/dist/modules/input.d.ts.map +1 -1
- package/dist/modules/input.js +45 -1
- package/dist/modules/input.js.map +1 -1
- package/dist/modules/latest-render-scheduler.d.ts +19 -0
- package/dist/modules/latest-render-scheduler.d.ts.map +1 -0
- package/dist/modules/latest-render-scheduler.js +54 -0
- package/dist/modules/latest-render-scheduler.js.map +1 -0
- package/dist/modules/lightSensor.d.ts +44 -0
- package/dist/modules/lightSensor.d.ts.map +1 -0
- package/dist/modules/lightSensor.js +33 -0
- package/dist/modules/lightSensor.js.map +1 -0
- package/dist/modules/mic.d.ts +3 -2
- package/dist/modules/mic.d.ts.map +1 -1
- package/dist/modules/mic.js +3 -2
- package/dist/modules/mic.js.map +1 -1
- package/dist/modules/miniapps.d.ts +2 -0
- package/dist/modules/miniapps.d.ts.map +1 -1
- package/dist/modules/miniapps.js.map +1 -1
- package/dist/modules/mirror.d.ts +16 -0
- package/dist/modules/mirror.d.ts.map +1 -0
- package/dist/modules/mirror.js +40 -0
- package/dist/modules/mirror.js.map +1 -0
- package/dist/modules/mono-text-rows.d.ts +20 -0
- package/dist/modules/mono-text-rows.d.ts.map +1 -0
- package/dist/modules/mono-text-rows.js +26 -0
- package/dist/modules/mono-text-rows.js.map +1 -0
- package/dist/modules/navigation.d.ts.map +1 -1
- package/dist/modules/navigation.js +21 -14
- package/dist/modules/navigation.js.map +1 -1
- package/dist/modules/phone.d.ts +26 -1
- package/dist/modules/phone.d.ts.map +1 -1
- package/dist/modules/phone.js +28 -0
- package/dist/modules/phone.js.map +1 -1
- package/dist/modules/settings.d.ts +45 -0
- package/dist/modules/settings.d.ts.map +1 -0
- package/dist/modules/settings.js +54 -0
- package/dist/modules/settings.js.map +1 -0
- package/dist/modules/system.d.ts +21 -0
- package/dist/modules/system.d.ts.map +1 -1
- package/dist/modules/system.js +12 -0
- package/dist/modules/system.js.map +1 -1
- package/dist/modules/transcription.d.ts +3 -2
- package/dist/modules/transcription.d.ts.map +1 -1
- package/dist/modules/transcription.js +3 -2
- package/dist/modules/transcription.js.map +1 -1
- package/dist/protocol.d.ts +65 -5
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +66 -5
- package/dist/protocol.js.map +1 -1
- package/dist/react/MirrorCanvas.d.ts +10 -0
- package/dist/react/MirrorCanvas.d.ts.map +1 -0
- package/dist/react/MirrorCanvas.js +23 -0
- package/dist/react/MirrorCanvas.js.map +1 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/react/useColorScheme.d.ts +2 -3
- package/dist/react/useColorScheme.d.ts.map +1 -1
- package/dist/react/useColorScheme.js +15 -8
- package/dist/react/useColorScheme.js.map +1 -1
- package/dist/react/useRpc.js +2 -2
- package/dist/react/useRpc.js.map +1 -1
- package/dist/react/useSafeArea.d.ts.map +1 -1
- package/dist/react/useSafeArea.js +2 -2
- package/dist/react/useSafeArea.js.map +1 -1
- package/dist/session.d.ts +50 -4
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +35 -6
- package/dist/session.js.map +1 -1
- package/dist/transport/auto.d.ts +2 -2
- package/dist/transport/auto.js +2 -2
- package/dist/transport/dispatch.d.ts +1 -1
- package/dist/transport/dispatch.js +1 -1
- package/dist/transport/mock.d.ts +4 -4
- package/dist/transport/mock.d.ts.map +1 -1
- package/dist/transport/mock.js +31 -7
- package/dist/transport/mock.js.map +1 -1
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -0
- package/dist/ui/index.js.map +1 -1
- package/package.json +19 -3
- package/src/background/index.ts +26 -4
- package/src/background/register.ts +1 -1
- package/src/display/index.ts +83 -0
- package/src/display/measurer/TextMeasurer.ts +346 -0
- package/src/display/measurer/index.ts +21 -0
- package/src/display/measurer/script-detection.ts +218 -0
- package/src/display/pixelArt.ts +141 -0
- package/src/display/profiles/g1.ts +237 -0
- package/src/display/profiles/g2.ts +39 -0
- package/src/display/profiles/index.ts +28 -0
- package/src/display/profiles/nex.ts +166 -0
- package/src/display/profiles/types.ts +132 -0
- package/src/display/profiles/z100.ts +198 -0
- package/src/display/scene/types.ts +335 -0
- package/src/display/wrapper/TextWrapper.ts +546 -0
- package/src/display/wrapper/index.ts +15 -0
- package/src/display/wrapper/types.ts +102 -0
- package/src/globals.ts +5 -5
- package/src/hardware.ts +6 -21
- package/src/index.ts +34 -6
- package/src/knownApps.ts +170 -0
- package/src/mirror/canvas.ts +322 -0
- package/src/mirror/geometry.ts +128 -0
- package/src/mirror/index.ts +2 -0
- package/src/mirror/types.ts +38 -0
- package/src/modules/auth.ts +2 -2
- package/src/modules/compass.ts +69 -0
- package/src/modules/display.ts +222 -12
- package/src/modules/events.ts +27 -1
- package/src/modules/input.ts +55 -2
- package/src/modules/latest-render-scheduler.ts +55 -0
- package/src/modules/lightSensor.ts +61 -0
- package/src/modules/mic.ts +3 -2
- package/src/modules/miniapps.ts +2 -0
- package/src/modules/mirror.ts +42 -0
- package/src/modules/mono-text-rows.ts +30 -0
- package/src/modules/navigation.ts +20 -14
- package/src/modules/phone.ts +40 -1
- package/src/modules/settings.ts +64 -0
- package/src/modules/system.ts +30 -1
- package/src/modules/transcription.ts +3 -2
- package/src/protocol.ts +72 -5
- package/src/react/MirrorCanvas.tsx +35 -0
- package/src/react/index.ts +3 -0
- package/src/react/useColorScheme.ts +17 -8
- package/src/react/useRpc.ts +2 -2
- package/src/react/useSafeArea.ts +2 -2
- package/src/session.ts +78 -8
- package/src/transport/auto.ts +2 -2
- package/src/transport/dispatch.ts +1 -1
- package/src/transport/mock.ts +42 -11
- package/src/ui/index.ts +3 -0
- package/dist/modules/heading.d.ts +0 -16
- package/dist/modules/heading.d.ts.map +0 -1
- package/dist/modules/heading.js +0 -20
- package/dist/modules/heading.js.map +0 -1
- package/src/modules/heading.ts +0 -23
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# @glassly/miniapp
|
|
2
2
|
|
|
3
|
-
SDK for building Glassly local miniapps
|
|
3
|
+
SDK for building Glassly local miniapps: static web apps that run inside the Glassly App's WebView and talk to smart glasses via a typed session API.
|
|
4
4
|
|
|
5
5
|
> Developing this SDK or running the in-repo example from a fresh clone? Start at the **[SDK developer guide](../../../sdk/README.md)** (setup, build loop, doc map).
|
|
6
6
|
> Per-module deep dives (return shapes, events, error codes): **[`sdk/docs/`](../../../sdk/docs/README.md)**.
|
|
7
|
-
> Companion package: **[`@glassly/miniapp-cli`](../../../sdk/miniapp-cli/README.md)
|
|
8
|
-
> Scaffolder: `bunx create-miniapp my-app`.
|
|
7
|
+
> Companion package: **[`@glassly/miniapp-cli`](../../../sdk/miniapp-cli/README.md)**, the `glassly-miniapp` CLI (`dev`, `release`, `pack`, `manifest`, `permission`, `hardware`, `schema`). Per-command docs live there.
|
|
8
|
+
> Scaffolder: `bunx @glassly/create-miniapp my-app`.
|
|
9
9
|
> Reference miniapp: [`miniapps/example-miniapp/`](../../../miniapps/example-miniapp).
|
|
10
|
-
> High-level walkthrough: [`
|
|
10
|
+
> High-level walkthrough: [`notes/miniapp-sdk-overview.md`](../../../notes/miniapp-sdk-overview.md).
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
@@ -17,17 +17,19 @@ bun add @glassly/miniapp
|
|
|
17
17
|
npm install @glassly/miniapp
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
`react` is an optional peer dependency
|
|
20
|
+
`react` is an optional peer dependency, required only if you use `@glassly/miniapp/react`.
|
|
21
21
|
|
|
22
22
|
## Entry points
|
|
23
23
|
|
|
24
24
|
| Specifier | Contents |
|
|
25
25
|
| ---------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
26
26
|
| `@glassly/miniapp` | `MiniappSession`, `NotConnectedError`, transports, manifest-types re-exports, module type exports |
|
|
27
|
-
| `@glassly/miniapp/background` | `MiniappSession`, `registerMiniapp
|
|
27
|
+
| `@glassly/miniapp/background` | `MiniappSession`, `registerMiniapp`, the always-on session layer (see two-layer note below) |
|
|
28
28
|
| `@glassly/miniapp/ui` | The WebView-side `glassly` channel bridge + React adapters (`<MiniappProvider>`, `<MiniappHeader>`, hooks) |
|
|
29
29
|
| `@glassly/miniapp/react` | React hooks + `<MiniappProvider>` + `<MiniappHeader>` (also re-exported from `/ui`) |
|
|
30
30
|
| `@glassly/miniapp/protocol` | `MiniappRequestType`, `MiniappResponseType`, `MiniappStreamType`, `MiniappErrorCode` |
|
|
31
|
+
| `@glassly/miniapp/hardware` | `HardwareType`, `HardwareRequirementLevel`, `HardwareRequirement` (manifest hardware-requirement types) |
|
|
32
|
+
| `@glassly/miniapp/known-apps` | `KNOWN_APPS`, `knownApp`, `knownAppName`, `appGlyph` (notification app names and card glyphs by bundle id / package name) |
|
|
31
33
|
|
|
32
34
|
> **Two layers.** Miniapps split into an always-on **background** layer that
|
|
33
35
|
> owns the `MiniappSession` (`@glassly/miniapp/background`, entered via
|
|
@@ -47,14 +49,14 @@ import {registerMiniapp} from "@glassly/miniapp/background"
|
|
|
47
49
|
// before invoking your handler.
|
|
48
50
|
registerMiniapp((session) => {
|
|
49
51
|
// render() replaces the whole frame; stable ids update in place, render([]) clears.
|
|
50
|
-
const box = {x: 0, y: 0, w: 576, h: 288} // raw device px
|
|
52
|
+
const box = {x: 0, y: 0, w: 576, h: 288} // raw device px, see session.capabilities.display
|
|
51
53
|
session.display.render([{type: "text", id: "hello", box, text: "hello"}])
|
|
52
54
|
const unsub = session.transcription.on((d) => session.display.render([{type: "text", id: "hello", box, text: d.text}]))
|
|
53
55
|
// later: unsub()
|
|
54
56
|
})
|
|
55
57
|
```
|
|
56
58
|
|
|
57
|
-
UI layer (WebView React app
|
|
59
|
+
UI layer (WebView React app, no session here):
|
|
58
60
|
|
|
59
61
|
```tsx
|
|
60
62
|
import {MiniappProvider, useConnected} from "@glassly/miniapp/ui"
|
|
@@ -73,6 +75,34 @@ function App() {
|
|
|
73
75
|
|
|
74
76
|
## Session
|
|
75
77
|
|
|
78
|
+
### Shared display primitives
|
|
79
|
+
|
|
80
|
+
Import `TextMeasurer`, `TextWrapper`, display profiles, and pixel-art helpers
|
|
81
|
+
from `@glassly/miniapp/display`. These pure TypeScript primitives share the
|
|
82
|
+
host's implementation and work in either miniapp layer. See the
|
|
83
|
+
[display primitives reference](../../../sdk/docs/display-primitives.md).
|
|
84
|
+
|
|
85
|
+
### Opt-in display helpers
|
|
86
|
+
|
|
87
|
+
Both the main and `/background` entry points export:
|
|
88
|
+
|
|
89
|
+
- `monoTextRows({id, text, box, fontSize})`: stable-ID row elements for G2 CFW
|
|
90
|
+
fixed-pitch grids. Uses its 2px text inset and rounded 1.2× line pitch.
|
|
91
|
+
Unsupported Unicode falls back per row instead of rasterizing the entire
|
|
92
|
+
grid. Check positioned-text and element budgets first; this does not make
|
|
93
|
+
stock firmware support dense mono grids. Submit all rows in each scene,
|
|
94
|
+
including blank rows, so deletions clear correctly.
|
|
95
|
+
- `LatestRenderScheduler(() => intervalMs)`: `request(async () => { ... })`
|
|
96
|
+
runs one callback at a time, keeping only the latest pending callback.
|
|
97
|
+
Construct the scene inside the callback and await `display.render()`;
|
|
98
|
+
report failures there. Call `clearPending()` when changing views and
|
|
99
|
+
`dispose()` on shutdown. It cannot cancel native work already submitted,
|
|
100
|
+
does not change global FPS/transport settings, and must never be used to
|
|
101
|
+
discard input bytes or other non-replaceable events.
|
|
102
|
+
|
|
103
|
+
These are optional producer-side helpers, not an automatic native Unicode
|
|
104
|
+
renderer change or BLE message pipelining.
|
|
105
|
+
|
|
76
106
|
`MiniappSession` is the only object you construct. It owns the transport, the request/response correlation map, the pre-ready outbound queue, the keepalive PONG, and the cached visibility / capabilities / color-scheme / permissions state.
|
|
77
107
|
|
|
78
108
|
### Lifecycle
|
|
@@ -86,9 +116,9 @@ session.disconnect()
|
|
|
86
116
|
|
|
87
117
|
`MiniappSessionOptions`:
|
|
88
118
|
|
|
89
|
-
- `packageName?: string
|
|
90
|
-
- `connectTimeoutMs?: number
|
|
91
|
-
- transport-selection options from `createTransport` (`
|
|
119
|
+
- `packageName?: string`: overrides auto-detection from `window.Glassly`
|
|
120
|
+
- `connectTimeoutMs?: number`: defaults to 10s
|
|
121
|
+
- transport-selection options from `createTransport` (`transport`, `localSocketUrl`)
|
|
92
122
|
|
|
93
123
|
### Lifecycle events
|
|
94
124
|
|
|
@@ -99,52 +129,81 @@ session.off("ready", handler)
|
|
|
99
129
|
|
|
100
130
|
| Event | Signature |
|
|
101
131
|
| -------------- | --------------------------------------------- |
|
|
102
|
-
| `ready`
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
110
|
-
|
|
111
|
-
|
|
132
|
+
| `ready` | `() => void`, fires after CONNECT_ACK |
|
|
133
|
+
| `beforeDisconnect` | `(reason: string) => void`, last chance to send one final one-shot |
|
|
134
|
+
| `disconnect` | `(reason: string) => void` |
|
|
135
|
+
| `error` | `(err: Error) => void` |
|
|
136
|
+
| `visibility` | `("foreground" \| "background") => void` |
|
|
137
|
+
| `capabilities` | `(caps: GlassesCapabilities \| null) => void` |
|
|
138
|
+
| `preferences` | `(prefs: MiniappPreferences) => void` |
|
|
139
|
+
| `colorScheme` | `("light" \| "dark") => void` |
|
|
140
|
+
| `permissions` | `(perms: PermissionRecord) => void` |
|
|
141
|
+
| `speakerState` | `(event: SpeakerStateEvent) => void` |
|
|
142
|
+
| `auth` | `(auth: MiniappAuthState) => void` |
|
|
143
|
+
|
|
144
|
+
Convenience wrappers: `onVisibilityChange`, `onCapabilitiesChange`, `onPreferencesChange`, `onColorSchemeChange`, `onBeforeDisconnect`. Each `on(...)` call also returns an unsubscribe function.
|
|
112
145
|
|
|
113
146
|
### Cached state
|
|
114
147
|
|
|
115
|
-
`session.userId`, `session.packageName`, `session.capabilities`, `session.visibility`, `session.colorScheme`, `session.ready`
|
|
148
|
+
`session.userId`, `session.packageName`, `session.capabilities`, `session.preferences`, `session.visibility`, `session.colorScheme`, `session.launchSource`, `session.ready` are populated from `CONNECT_ACK` and kept in sync via the lifecycle events above.
|
|
149
|
+
|
|
150
|
+
`session.preferences` is `{unitSystem: "metric" | "imperial", twelveHourTime: boolean}`, mirroring the host's Settings > Appearance toggles. Follow it for distances, temperatures and clock formatting unless your miniapp offers its own override. It is `null` on runtimes that predate the preferences surface, so fall back rather than assuming a value.
|
|
151
|
+
|
|
152
|
+
`session.launchSource` is `"phone"` or `"glasses"` — where the user started this session from — and `null` until `CONNECT_ACK` arrives, or on runtimes that don't send it.
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
const twelveHour = session.preferences?.twelveHourTime ?? true
|
|
156
|
+
session.onPreferencesChange((prefs) => rerender(prefs))
|
|
157
|
+
|
|
158
|
+
if (session.launchSource === "glasses") openGlassesFirstView()
|
|
159
|
+
```
|
|
116
160
|
|
|
117
161
|
## Modules
|
|
118
162
|
|
|
119
163
|
All event subscribers return an `UnsubscribeFn`. Subscriptions are ref-counted: the SDK sends `SUBSCRIBE` when a stream's active state or routing metadata changes.
|
|
120
164
|
|
|
121
|
-
| Module | Methods
|
|
122
|
-
|
|
|
123
|
-
| `session.
|
|
124
|
-
| `session.
|
|
125
|
-
| `session.
|
|
126
|
-
| `session.
|
|
127
|
-
| `session.
|
|
128
|
-
| `session.
|
|
129
|
-
| `session.
|
|
130
|
-
| `session.
|
|
131
|
-
| `session.
|
|
132
|
-
| `session.
|
|
133
|
-
| `session.
|
|
134
|
-
| `session.
|
|
135
|
-
| `session.
|
|
136
|
-
| `session.
|
|
137
|
-
| `session.led`
|
|
138
|
-
| `session.
|
|
139
|
-
| `session.
|
|
140
|
-
| `session.
|
|
141
|
-
| `session.
|
|
142
|
-
|
|
143
|
-
`session.
|
|
165
|
+
| Module | Methods |
|
|
166
|
+
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
167
|
+
| `session.auth` | `current`, `userId`, `oemId`, `getToken(opts?)`, `getAuthHeader(opts?)`, `fetch(input, init?)`, `onUpdate(handler)`; miniapp-scoped backend auth, never a Core or runtime token |
|
|
168
|
+
| `session.mirror` | `getCurrent()`, `onUpdate(handler)`, `hasPermission`; DISPLAY_MIRROR-gated global glasses preview; see [mirror reference](../../../sdk/docs/mirror.md) |
|
|
169
|
+
| `session.display` | `showView(view)`, `onViewChange(handler)` for overlay miniapps; `render(elements, opts?)`, scene API: diffed frames, stable-id in-place updates, `render([])` clears; `sendNativeNavInfo`/`sendNativeNavMiniMap`/`sendNativeNavOverviewMap` feed firmware-rendered navigation on devices with `hasNativeNavigation` |
|
|
170
|
+
| `session.speaker` | `state` (`"idle" \| "loading" \| "playing" \| "stopped" \| "error"`), `isPlaying` (true iff `state === "playing"`), `play({audioUrl})`, `speak(text, options?)`, `createStream({sampleRate?, volume?})` for bounded 16-bit PCM output, `stop()`, `onStateChange(handler)` |
|
|
171
|
+
| `session.camera` | `takePhoto({size?, mode?, transferMethod?, compress?, sound?, saveToGallery?, zsl?, mfnr?, timeoutMs?, ...})`, `setFov({fov, roiPosition?} \| {preset})`, `warmUp(opts?)`, `startVideoRecording(opts?)`, `stopVideoRecording(recordingId, opts?)`, `hasPermission` |
|
|
172
|
+
| `session.cloud` | `status`, `connected`, `isConnected()`, `onStatusChanged(handler)`; read-only view of the phone-owned cloud client's connection/audio-transport status |
|
|
173
|
+
| `session.dashboard` | `setContent(mode, content)` (noop in v1, prints a one-time `console.warn`); `showNativeDashboard()` brings the glasses' OS idle screen to the foreground |
|
|
174
|
+
| `session.glasses` | `onBattery(handler)`, `onConnection(handler)`, `onWifi(handler)`, `requestWifiSetup(reason?)`, `setWifiAdbState(enabled)` (SYSTEM-only) |
|
|
175
|
+
| `session.imu` | `onHeadPosition(handler)`, `onAccel(handler)`, `setEnabled(enabled)` |
|
|
176
|
+
| `session.compass` | `onUpdate(handler)`, `onCalibration(handler)`, `start(options?)`, `stop()`; glasses heading in degrees, auto-starts on G2 custom firmware, stock nav mode only |
|
|
177
|
+
| `session.lightSensor` | `onUpdate(handler)`, `query()`, `start(options?)`, `stop()`; G2 custom firmware ambient light, one controlling miniapp |
|
|
178
|
+
| `session.input` | `setClaimedGestures(gestures, {scope?})`, `onClaimChange(handler)`, `onButtonPress(handler)`, `onTouch(handler \| gesture, handler \| gestures, handler)` |
|
|
179
|
+
| `session.ai` | `complete(request)` (tier-based LLM completion, tool loop support), `generate(request, opts?)` (agentic visual generation), `prompt(text, opts?)` (single-shot text convenience), `hasPermission` |
|
|
180
|
+
| `session.keys` | `get(provider)`, read a user-supplied provider API key (anthropic/gemini/openai/elevenlabs/mapbox), `hasPermission` |
|
|
181
|
+
| `session.led` | `turnOn({color?, ontime?, offtime?, count?})`, `turnOff()`, `blink(color, ontime, offtime, count)`, `solid(color, duration)`; resolve after the glasses acknowledge the RGB command |
|
|
182
|
+
| `session.location` | `onUpdate(handler)`, `getOnce()`, `hasPermission` |
|
|
183
|
+
| `session.memory` | `appendLine(input)`, `addNote(text, source?, at?)`, `removeEntry(id)`, `removeScope(scope, at)`, `sessions()`, `query(q?)`, `search(q?)`, `window(sinceMs, untilMs?)`, `exportText(scope, at?)`, `addSummary(summary)`, `summaries()`, `pendingSummaryHour(nowMs?)`, `clear()`, `hasPermission`; the user's shared phone-local memory timeline |
|
|
184
|
+
| `session.speakers` | `resolveName(id)`, `hasPermission`; resolve an enrolled-speaker id to its display name |
|
|
185
|
+
| `session.mic` | `onAudioChunk(handler)`, `onVoiceActivity(handler)`, `setVoiceActivityDetectionEnabled(enabled)`, `setLoudnessGateEnabled(enabled)`, `stop()`, `hasPermission` |
|
|
186
|
+
| `session.navigation` | `start(opts)`, `stop()`, `onUpdate(handler)`, `onRoute(handler)`, `getState()`, `computeRoute(opts)`, `reverseGeocodeRoad(...)`, `placeAutocomplete(opts)`, `placeDetails(opts)`, `onPivot(handler)`, `getPivots()`, `getActivePivot()`, `getUpcomingPivot()`, `requestPermission()`, `hasPermission`; Android-only turn-by-turn navigation |
|
|
187
|
+
| `session.permissions` | `has(type)`, `getAll()`, `onUpdate(handler)`, `onPermissionError(handler)` |
|
|
188
|
+
| `session.phone.notifications` | `on(handler)`, `onDismissed(handler)`, `stop()`, `hasPermission`, `installedApps()` (SYSTEM-only) |
|
|
189
|
+
| `session.phone.calendar` | `listEvents({startsAt, endsAt, limit?})`, `hasPermission` |
|
|
190
|
+
| `session.phone` | `onBattery(handler)` |
|
|
191
|
+
| `session.settings` | `get(key)`, `getAll(keys?)`, `set(key, value)`, `onChange(handler)`; SYSTEM-only host settings bridge; see [settings reference](../../../sdk/docs/settings.md) |
|
|
192
|
+
| `session.storage` | `get(key)`, `set(key, value)`, `delete(key)`, `keys()`, `has(key)`, `getAll()`, `setMultiple(values)`, `clear()`, `flush()`; strings only, scoped to `(userId, packageName)` |
|
|
193
|
+
| `session.blob` | `set(key, data, opts?)`, `get(key)`, `stat(key)`, `has(key)`, `keys()`, `list()`, `setFromUrl(key, url, opts?)`, `importFile(opts?)`, `createWriteStream(key, opts?)`, `createReadStream(key)`, `bytes(key)`, `usage()`, `delete(key)`, `clear()`, `share(key)`; phone-local binary storage, chunked writes/reads |
|
|
194
|
+
| `session.stream` | `startStream(opts?)`, `stop(streamId?)`; managed (default, returns `hlsUrl`/`dashUrl`/`webrtcUrl` and optional `destinations` fan-out) or `direct` (publish straight to your own ingest URL, no playback URLs); `opts.ingest` selects `"srt"` (default), `"whip"`, or `"rtmp"`; video config fields are `width`, `height`, `bitrate`, `fps` |
|
|
195
|
+
| `session.system` | `share(opts)`, `openUrl(url)`, `copyToClipboard(text)`, `download(opts)`, `scanQr(opts?)`, `exit()`, `getDisplayDiagnostics()` |
|
|
196
|
+
| `session.transcription` | `on(handler, {forceLocal?})`, `forLanguage(lang \| [langs], handler, {forceLocal?})`, `configure({languageHints, vocabulary, diarization})`, `stop()`, `hasPermission` |
|
|
197
|
+
| `session.translation` | `on(handler)`, `to(target \| [targets], handler)`, `fromTo(source, target \| [targets], handler)`, `stop()`, `hasPermission` |
|
|
198
|
+
| `session.ui` | `isOpen()`, `onOpen(handler)`, `onClose(handler)`, `send(channel, payload)`, `on(channel, handler)`, `handle(channel, handler)`; background-side message bus to the bound WebView; see [Wire protocol](#wire-protocol) and [`sdk/docs/two-layer.md`](../../../sdk/docs/two-layer.md) |
|
|
199
|
+
| `session.miniapps` | `list(opts?)`, `start(packageName)`, `stop(packageName)`, `stopSelf()`; inter-miniapp lifecycle and discovery, SYSTEM-only except `stopSelf()` |
|
|
200
|
+
| `session.actions` | `list()`, `invoke(packageName, actionId, params?, opts?)`, `handle(actionId, handler)`; inter-miniapp action layer (MCP-tool-shaped); `list`/`invoke` open to all, gated per-action by the target's declared `visibility` |
|
|
201
|
+
|
|
202
|
+
`session.events` is internal. It exposes `subscribe(rawStreamType, handler)` only as a forward-compat escape hatch for new event types not yet wrapped on a domain module; prefer the typed module surface.
|
|
144
203
|
|
|
145
204
|
### Camera FOV
|
|
146
205
|
|
|
147
|
-
`await session.camera.setFov({fov, roiPosition})` applies a temporary, miniapp-owned FOV/ROI override and resolves with `CameraFovResult` after the ASG client reports the setting was applied following the camera restart cooldown. The host restores the previous live miniapp override
|
|
206
|
+
`await session.camera.setFov({fov, roiPosition})` applies a temporary, miniapp-owned FOV/ROI override and resolves with `CameraFovResult` after the ASG client reports the setting was applied following the camera restart cooldown. The host restores the previous live miniapp override, or the persistent 118-degree full-sensor base, when this miniapp closes. `roiPosition` accepts `"center"`, `"bottom"`, or `"top"` and defaults to `"center"`. You can also call `setFov({preset: "narrow" | "standard" | "wide"})`; presets map to 82, 102, and 118 degrees with center ROI. The call requires `CAMERA` in `miniapp.json` and rejects with `MiniappRequestError` if the host or glasses cannot apply it.
|
|
148
207
|
|
|
149
208
|
### Camera Photos
|
|
150
209
|
|
|
@@ -154,36 +213,36 @@ Pass `transferMethod: "ble"` to skip direct Wi-Fi upload and always relay the im
|
|
|
154
213
|
|
|
155
214
|
### Transcription language convention
|
|
156
215
|
|
|
157
|
-
Transcription/translation streams use a colon-suffixed wire format: `transcription:en-US`, `translation:en-US:fr-FR`. `session.transcription.on(handler)` subscribes to `transcription:auto` (cloud auto-detects). The detected language is in the payload. A handler on `transcription:auto` receives any `transcription:<lang>` event
|
|
216
|
+
Transcription/translation streams use a colon-suffixed wire format: `transcription:en-US`, `translation:en-US:fr-FR`. `session.transcription.on(handler)` subscribes to `transcription:auto` (cloud auto-detects). The detected language is in the payload. A handler on `transcription:auto` receives any `transcription:<lang>` event, a wildcard fan-out, so "give me transcripts in whatever language" works without manual wiring. Use `session.transcription.forLanguage(lang | [langs], handler)` to pin specific languages. Pass `{forceLocal: true}` as the final argument to either method to require on-device transcription and suppress cloud results for that subscription. Routing is per listener, so a default listener on the same stream can continue receiving cloud transcription.
|
|
158
217
|
|
|
159
218
|
### Permissions semantics
|
|
160
219
|
|
|
161
|
-
`session.permissions.has("microphone")` returns whether the manifest declared the permission. Same semantics as cloud SDK v3.
|
|
220
|
+
`session.permissions.has("microphone")` returns whether the manifest declared the permission. Same semantics as cloud SDK v3. It does *not* report OS-level grant state: even when `has(...)` returns `true` the user can have denied the OS prompt and your subscriptions will silently receive no events. OS-grant tracking and `request(...)` are deferred and will land additively on the same module.
|
|
162
221
|
|
|
163
|
-
`PermissionType` is the lowercase canonical union: `"location" | "microphone" | "camera" | "notifications" | "calendar"`. Manifest UPPER_CASE names map onto these (`BACKGROUND_LOCATION` → `location`; `READ_NOTIFICATIONS`, `POST_NOTIFICATIONS` → `notifications`).
|
|
222
|
+
`PermissionType` is the lowercase canonical union: `"location" | "microphone" | "camera" | "notifications" | "calendar" | "apiKeys" | "memory" | "ai" | "speakers"`. Manifest UPPER_CASE names map onto these (`BACKGROUND_LOCATION` → `location`; `READ_NOTIFICATIONS`, `POST_NOTIFICATIONS` → `notifications`; `API_KEYS` → `apiKeys`; `MEMORY` → `memory`; `AI` → `ai`; `SPEAKERS` → `speakers`).
|
|
164
223
|
|
|
165
|
-
## React bindings
|
|
224
|
+
## React bindings (`@glassly/miniapp/ui`)
|
|
166
225
|
|
|
167
226
|
These UI-layer hooks run inside the WebView and read host state via the injected
|
|
168
|
-
`glassly` channel bridge / `window.Glassly` globals
|
|
227
|
+
`glassly` channel bridge / `window.Glassly` globals; they do not own a
|
|
169
228
|
`MiniappSession` (that lives in the background layer). They are also re-exported
|
|
170
229
|
from `@glassly/miniapp/react` for backwards-compat.
|
|
171
230
|
|
|
172
231
|
| Hook | Returns |
|
|
173
232
|
| ------------------------- | ------------------------------------------------------------------------------------------ |
|
|
174
|
-
| `useConnected()` | `boolean
|
|
175
|
-
| `useCapabilities()` | Glasses capability profile
|
|
233
|
+
| `useConnected()` | `boolean`, true while the `glassly` bridge is open (`onOpen` / `onClose`) |
|
|
234
|
+
| `useCapabilities()` | Glasses capability profile; currently always `null` on the UI side (caps arrive over a channel) |
|
|
176
235
|
| `useColorScheme()` | `"light" \| "dark"` (host theme) |
|
|
177
|
-
| `useSafeArea()` | `{insets, capsuleMenu}
|
|
236
|
+
| `useSafeArea()` | `{insets, capsuleMenu}`, pixel insets and bounding rect of the host's floating capsule menu |
|
|
178
237
|
| `useCapsuleHeaderStyle()` | Pre-computed CSS for a header row that aligns with the capsule menu |
|
|
179
238
|
| `useRpc(...)` | Typed request helper over the `glassly` channel bridge |
|
|
180
239
|
|
|
181
240
|
Components:
|
|
182
241
|
|
|
183
|
-
- `<MiniappProvider
|
|
184
|
-
- `<MiniappHeader title="…" left={…} right={…} onBack={…}
|
|
242
|
+
- `<MiniappProvider>`: root provider. Keeps `<html class="dark">` in sync with the host color scheme during render (no FOUC).
|
|
243
|
+
- `<MiniappHeader title="…" left={…} right={…} onBack={…} />`: drop-in header that respects the safe area and leaves room for the capsule menu.
|
|
185
244
|
|
|
186
|
-
## Manifest
|
|
245
|
+
## Manifest (`miniapp.json`)
|
|
187
246
|
|
|
188
247
|
```json
|
|
189
248
|
{
|
|
@@ -200,8 +259,8 @@ Components:
|
|
|
200
259
|
}
|
|
201
260
|
```
|
|
202
261
|
|
|
203
|
-
- `permissions[].type` ∈ `MICROPHONE | CAMERA | CALENDAR | LOCATION | BACKGROUND_LOCATION | READ_NOTIFICATIONS | POST_NOTIFICATIONS`
|
|
204
|
-
- `hardwareRequirements[].type` ∈ `CAMERA | DISPLAY | MICROPHONE | SPEAKER | IMU | BUTTON | LIGHT | WIFI`, `level` ∈ `REQUIRED | OPTIONAL`
|
|
262
|
+
- `permissions[].type` ∈ `MICROPHONE | CAMERA | CALENDAR | LOCATION | BACKGROUND_LOCATION | READ_NOTIFICATIONS | POST_NOTIFICATIONS | API_KEYS | MEMORY | AI | SPEAKERS`
|
|
263
|
+
- `hardwareRequirements[].type` ∈ `CAMERA | DISPLAY | MICROPHONE | SPEAKER | IMU | BUTTON | LIGHT | WIFI`, `level` ∈ `REQUIRED | OPTIONAL`. (`EXIST` also exists on the wire but the phone injects it at runtime; don't declare it.)
|
|
205
264
|
|
|
206
265
|
The CLI validates the manifest on every `dev`, `release`, and `pack`. Run `glassly-miniapp schema print` for the canonical JSON Schema.
|
|
207
266
|
|
|
@@ -221,9 +280,9 @@ The author-facing CLI lives in a sibling package: **[`@glassly/miniapp-cli`](../
|
|
|
221
280
|
|
|
222
281
|
See [the CLI README](../../../sdk/miniapp-cli/README.md) for flags, semantics, and the `miniapp://` URL schemes the QR codes encode.
|
|
223
282
|
|
|
224
|
-
## Host-injected globals
|
|
283
|
+
## Host-injected globals (`window.Glassly`)
|
|
225
284
|
|
|
226
|
-
The Glassly
|
|
285
|
+
The Glassly App injects this before content loads. Authors generally use the React hooks instead, but the raw shape is:
|
|
227
286
|
|
|
228
287
|
```ts
|
|
229
288
|
{
|
|
@@ -235,37 +294,41 @@ The Glassly app injects this before content loads. Authors generally use the Rea
|
|
|
235
294
|
}
|
|
236
295
|
```
|
|
237
296
|
|
|
238
|
-
Use `
|
|
297
|
+
Use `getHostGlobals()` (exported from the package) to read it with the right TypeScript types.
|
|
239
298
|
|
|
240
299
|
## Transports
|
|
241
300
|
|
|
242
|
-
Auto-selected by `createTransport(options)
|
|
301
|
+
Auto-selected by `createTransport(options)`, in this order:
|
|
302
|
+
|
|
303
|
+
- `DispatchTransport`: the production path. Used when running in the per-miniapp background JSContext (no DOM, but the native bridge installs `__dispatch` on `globalThis`). Rides `__dispatch("__bridge", "send", ...)` outbound and the polyfill's `__deliverBridgeRaw` inbound.
|
|
304
|
+
- `PostMessageTransport`: used inside the Glassly WebView (`window.ReactNativeWebView` defined). `window.ReactNativeWebView.postMessage` outbound, `window` `message` listener inbound.
|
|
305
|
+
- `MockTransport`: explicit opt-in via `?glassly=mock` or `localStorage.MINIAPP_MOCK=1`. Synthesizes a CONNECT_ACK and REQUEST_RESULT replies so the SDK doesn't hang in a plain browser tab.
|
|
306
|
+
- `LocalSocketTransport`: fallback for laptop browsers with `WebSocket` available. Default endpoint `ws://127.0.0.1:8765`. Races open() against a 500ms timeout and falls back to `MockTransport` if nothing answers.
|
|
243
307
|
|
|
244
|
-
|
|
245
|
-
- **`LocalSocketTransport`** — fallback for laptop browsers. Default endpoint `ws://127.0.0.1:8765`. The in-laptop-browser dev story is currently broken; see the overview doc for status.
|
|
308
|
+
`createTransport(options)` takes `{transport?, localSocketUrl?}`. Pass `transport` to force a specific instance (tests), or `localSocketUrl` to override the LocalSocket fallback's URL.
|
|
246
309
|
|
|
247
|
-
|
|
310
|
+
All four are exported for advanced uses (forced transport, tests).
|
|
248
311
|
|
|
249
312
|
## Wire protocol
|
|
250
313
|
|
|
251
314
|
Every message is a `{payload, requestId?}` envelope, JSON over the chosen transport. `requestId` correlates request ↔ response for methods that return a value. Constants live in `@glassly/miniapp/protocol`:
|
|
252
315
|
|
|
253
|
-
- `MiniappRequestType
|
|
254
|
-
- `MiniappResponseType
|
|
255
|
-
- `MiniappStreamType
|
|
256
|
-
- `MiniappErrorCode
|
|
316
|
+
- `MiniappRequestType`: `CONNECT`, `SUBSCRIBE`, etc.
|
|
317
|
+
- `MiniappResponseType`: `CONNECT_ACK`, `EVENT`, `REQUEST_RESULT`, `PERMISSIONS_UPDATE`, …
|
|
318
|
+
- `MiniappStreamType`: typed names for stream identifiers
|
|
319
|
+
- `MiniappErrorCode`: `NOT_CONNECTED`, `PERMISSION_NOT_DECLARED`, …
|
|
257
320
|
|
|
258
321
|
Full enum listings in [`src/protocol.ts`](./src/protocol.ts).
|
|
259
322
|
|
|
260
323
|
## Controller pattern (recommended)
|
|
261
324
|
|
|
262
|
-
Smart-glasses miniapps are
|
|
325
|
+
Smart-glasses miniapps are always-on services. The webview is a UI on top of a continuously-running session. If you tie subscriptions to React component lifecycle, closing or navigating away from a page also stops the glasses behavior, the wrong shape for glasses.
|
|
263
326
|
|
|
264
|
-
|
|
327
|
+
User-facing glasses logic lives in a session-scoped controller, instantiated once in the background layer's `registerMiniapp` handler. The controller owns every `session.*` subscription and pushes state to the WebView over `session.ui.send` channels; UI pages read that pushed state (e.g. with a small `useChannel`-style hook wrapping `glassly.on`) and call back into the controller for user-triggered actions via `session.ui.handle`/`glassly.request`. Pages do not construct or subscribe to a `session.*` module directly. The background JSContext and the WebView are separate runtimes, so there is no shared in-memory store between them.
|
|
265
328
|
|
|
266
|
-
See [`miniapps/example-miniapp/src/background/controllers/GlassesController.ts`](../../../miniapps/example-miniapp/src/background/controllers/GlassesController.ts) for a worked reference.
|
|
329
|
+
See [`miniapps/example-miniapp/src/background/controllers/GlassesController.ts`](../../../miniapps/example-miniapp/src/background/controllers/GlassesController.ts) and [`miniapps/example-miniapp/src/ui/hooks/useChannel.ts`](../../../miniapps/example-miniapp/src/ui/hooks/useChannel.ts) for a worked reference.
|
|
267
330
|
|
|
268
|
-
|
|
331
|
+
Tester pages exception: `pages/tester/*` are diagnostic surfaces; by design they inline-subscribe to `session.*` and tear down on unmount. This is the only place where that pattern is acceptable.
|
|
269
332
|
|
|
270
333
|
## File map
|
|
271
334
|
|
|
@@ -273,3 +336,85 @@ See [`miniapps/example-miniapp/src/background/controllers/GlassesController.ts`]
|
|
|
273
336
|
- CLI: [`../miniapp-cli/src/`](../../../sdk/miniapp-cli/src/)
|
|
274
337
|
- Scaffolder: [`../create-miniapp/`](../../../sdk/create-miniapp/)
|
|
275
338
|
- Reference miniapp: [`miniapps/example-miniapp/`](../../../miniapps/example-miniapp/)
|
|
339
|
+
|
|
340
|
+
## SVG paths and rotation
|
|
341
|
+
|
|
342
|
+
G2 Glassly CFW revision 21 and Simulated Glasses support filled SVG paths and
|
|
343
|
+
clockwise rotation of geometric elements. Check
|
|
344
|
+
`session.capabilities.display.shapes.includes("svg")` and
|
|
345
|
+
`session.capabilities.display.rotation` before using them.
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
const heart = {
|
|
349
|
+
type: "svg" as const,
|
|
350
|
+
id: "heart",
|
|
351
|
+
box: {x: 60, y: 60, w: 120, h: 120},
|
|
352
|
+
d: "M50 90 C-10 45 0 0 30 10 Q45 10 50 25 Q55 10 70 10 C100 0 110 45 50 90 Z",
|
|
353
|
+
scale: 1,
|
|
354
|
+
rotation: 0,
|
|
355
|
+
pivot: {x: 120, y: 120},
|
|
356
|
+
}
|
|
357
|
+
await session.display.render([heart])
|
|
358
|
+
// Keep the id and d: the firmware reuses the path while moving and turning it.
|
|
359
|
+
await session.display.render([{...heart, box: {...heart.box, x: 120}, scale: 1.5,
|
|
360
|
+
rotation: 720, transition: {durationMs: 2000, easing: "ease-in-out"}}])
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
`d` accepts absolute/relative `M L H V Q C S T Z` and implicit repetitions.
|
|
364
|
+
Every contour must close with `Z`; `fillRule` is `"nonzero"` (default) or
|
|
365
|
+
`"evenodd"`. This is SVG path data, not an XML document: arcs, strokes, gradients,
|
|
366
|
+
CSS and SVG transform attributes must be converted before calling `render`.
|
|
367
|
+
|
|
368
|
+
Path coordinates are local to `box.x/y`; `scale` uniformly scales them (0–8,
|
|
369
|
+
quantized to 1/256). `box.w/h` describe layout bounds and do not stretch the path
|
|
370
|
+
or clip its curves. Source coordinates must fit signed Q4 (−2048 to 2047.9375).
|
|
371
|
+
|
|
372
|
+
## Depth and cards on top
|
|
373
|
+
|
|
374
|
+
Every element takes an optional `depth` (−16..16 canvas px): a stereo disparity
|
|
375
|
+
drawn on devices whose `session.capabilities.display.depth` is true, flat
|
|
376
|
+
everywhere else. Positive floats the element in front of the frame. Elements
|
|
377
|
+
still paint in array order, so a card that should sit on top of running content
|
|
378
|
+
goes last in the array and at a positive depth. A `transition` animates a move
|
|
379
|
+
or a depth change. This example moves a card within a G2-sized canvas:
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
import type {RenderElement} from "@glassly/miniapp/background"
|
|
383
|
+
|
|
384
|
+
const content: RenderElement[] = [] // the rest of your scene
|
|
385
|
+
const card = (x: number): RenderElement[] => [
|
|
386
|
+
{type: "rect" as const, id: "card", box: {x, y: 70, w: 300, h: 150},
|
|
387
|
+
style: {fill: true, color: 2, radius: 10}, depth: 8, transition: {durationMs: 350, easing: "ease-out"}},
|
|
388
|
+
{type: "text" as const, id: "card-title", box: {x: x + 16, y: 82, w: 268, h: 30}, text: "Incoming call",
|
|
389
|
+
style: {font: "builtin"}, depth: 8, transition: {durationMs: 350, easing: "ease-out"}},
|
|
390
|
+
]
|
|
391
|
+
await session.display.render([...content, ...card(20)]) // initial position
|
|
392
|
+
await session.display.render([...content, ...card(252)]) // glides in, 8 px in front
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
The example miniapp's **Tester → cards + depth** suite exercises static depth,
|
|
396
|
+
depth in motion, slide in/out, stacks and cache reopen.
|
|
397
|
+
|
|
398
|
+
The host rejects paths exceeding 8,192 command bytes, 1,024 commands or 512
|
|
399
|
+
flattened edges, and caps the scene at 4,096 path edges. Invalid/unsupported
|
|
400
|
+
elements are reported in `RenderResult.dropped`.
|
|
401
|
+
|
|
402
|
+
`rotation` uses unwrapped degrees (±36,000): 720 means two clockwise turns.
|
|
403
|
+
`pivot` is a fixed point in canvas coordinates; it defaults to the target box's
|
|
404
|
+
center. Rotation applies to rectangles, circles, lines, polygons, Béziers, arcs,
|
|
405
|
+
pies and SVGs. Text and images do not rotate. Rotation duration is capped at
|
|
406
|
+
65,535 ms; existing geometry tweens retain their 255-frame limit (about 8.4 s).
|
|
407
|
+
Geometry and rotation run independently. Creating/replacing a path snaps;
|
|
408
|
+
stable paths tween position, scale, color and rotation. Contour morphing is not
|
|
409
|
+
implemented. The simulated display previews these transforms and transitions.
|
|
410
|
+
|
|
411
|
+
### Glasses compass and light sensor
|
|
412
|
+
|
|
413
|
+
`session.compass` is the one glasses heading API: subscribing runs the sensor
|
|
414
|
+
(G2 custom firmware) or listens for the stock nav-mode heading; `start(options?)`
|
|
415
|
+
/ `stop()` only set this miniapp's sampling override and the phone serves the
|
|
416
|
+
tightest request across miniapps. The phone's own compass is
|
|
417
|
+
`session.phone.heading`. `session.lightSensor` exposes `onUpdate`, `query`,
|
|
418
|
+
`start(options?)`, and `stop` with one controlling miniapp. See
|
|
419
|
+
[imu.md](../../../sdk/docs/imu.md) and [lightsensor.md](../../../sdk/docs/lightsensor.md)
|
|
420
|
+
for units, options, ownership, and the example miniapp testers.
|
|
@@ -16,8 +16,10 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export { MiniappSession, type MiniappSessionOptions } from "../session";
|
|
18
18
|
export { registerMiniapp, type MiniappInitHandler, type TypedMiniappSession } from "./register";
|
|
19
|
-
export
|
|
20
|
-
export
|
|
19
|
+
export { monoTextRows } from "../modules/mono-text-rows";
|
|
20
|
+
export { LatestRenderScheduler } from "../modules/latest-render-scheduler";
|
|
21
|
+
export type { TranscriptionData, TranslationData, ButtonPressData, AudioChunkData, VadData, BatteryData, ConnectionData, WifiData, HeadPositionData, AccelData, LocationData, PhoneNotificationData, NotificationDismissedData, HeadingData, TouchData, KeyboardEventData, UnsubscribeFn, } from "../modules/events";
|
|
22
|
+
export type { CalendarEvent, CalendarListOptions, CalendarListResult, NotificationAppInfo } from "../modules/phone";
|
|
21
23
|
export { MiniappRequestType, MiniappResponseType, MiniappStreamType, MiniappErrorCode } from "../protocol";
|
|
22
24
|
export { MiniappValidationError, SUPPORTED_LANGUAGE_HINTS, SUPPORTED_TRANSCRIPTION_LANGUAGES, isTranscriptionLanguage, } from "../modules/languages";
|
|
23
25
|
export type { LanguageHint, TranscriptionLanguage } from "../modules/languages";
|
|
@@ -27,9 +29,8 @@ export type { CameraFovPreset, CameraFovRequest, CameraFovResult, CameraModule,
|
|
|
27
29
|
export type { CloudClientAudioTransport, CloudClientConnectionStatus, CloudClientStatus, CloudModule, } from "../modules/cloud";
|
|
28
30
|
export type { DashboardAPI } from "../modules/dashboard";
|
|
29
31
|
export type { GlassesModule } from "../modules/glasses";
|
|
30
|
-
export type { HeadingModule } from "../modules/heading";
|
|
31
32
|
export type { ImuModule } from "../modules/imu";
|
|
32
|
-
export type { InputModule } from "../modules/input";
|
|
33
|
+
export type { InputModule, GestureClaimChange } from "../modules/input";
|
|
33
34
|
export type { LedModule } from "../modules/led";
|
|
34
35
|
export type { LocationModule } from "../modules/location";
|
|
35
36
|
export type { MemoryModule, MemoryEntry, MemoryEntryKind, MemoryNoteSource, MemoryQuery, MemorySession, MemorySummary, } from "../modules/memory";
|
|
@@ -37,7 +38,8 @@ export type { SpeakersModule } from "../modules/speakers";
|
|
|
37
38
|
export type { MicModule } from "../modules/mic";
|
|
38
39
|
export type { NavigationModule } from "../modules/navigation";
|
|
39
40
|
export type { PermissionsModule } from "../modules/permissions";
|
|
40
|
-
export type { PhoneModule } from "../modules/phone";
|
|
41
|
+
export type { PhoneModule, PhoneHeadingModule } from "../modules/phone";
|
|
42
|
+
export type { SettingsModule, SettingsChange } from "../modules/settings";
|
|
41
43
|
export type { SimpleStorage } from "../modules/storage";
|
|
42
44
|
export { BlobModule, BlobWriter, BlobReader, BLOB_WRITE_CHUNK_BYTES, BLOB_READ_ALL_MAX_BYTES } from "../modules/blob";
|
|
43
45
|
export type { BlobMeta, BlobSetOptions, BlobSetFromUrlOptions, BlobImportOptions } from "../modules/blob";
|
|
@@ -51,14 +53,18 @@ export type { UIModule, UIChannelHandler, UIUnsubscribe } from "../modules/ui";
|
|
|
51
53
|
export type { Rpc, IsRpc, RpcReq, RpcRes, RpcRequestOptions, RpcHandlerContext } from "../modules/ui";
|
|
52
54
|
export { RpcError, RpcTimeoutError } from "../modules/ui";
|
|
53
55
|
export type { LedColor, LedControlOptions } from "../modules/led";
|
|
54
|
-
export type { ViewType, DisplayBreakMode, RenderBox, RenderElement, RenderOptions, RenderRectStyle, RenderResult, RenderTextStyle, } from "../modules/display";
|
|
56
|
+
export type { ViewType, DisplayBreakMode, RenderBox, RenderElement, RenderOptions, DisplayViewChange, DisplayViewChangeReason, ShowViewResult, RenderRectStyle, RenderResult, RenderTextStyle, } from "../modules/display";
|
|
55
57
|
export type { DashboardMode, ShowNativeDashboardResult } from "../modules/dashboard";
|
|
56
58
|
export type { PlayAudioOptions, SpeakOptions, SpeakResult, SpeakerState, SpeakerStateEvent } from "../modules/speaker";
|
|
57
|
-
export type { ShareOptions, ShareResult, DownloadOptions, DownloadResult, ScanQrOptions, ScanQrResult, } from "../modules/system";
|
|
59
|
+
export type { ShareOptions, ShareResult, DownloadOptions, DownloadResult, ScanQrOptions, ScanQrResult, DisplayDiagnostic, DisplayDiagnosticsResult, } from "../modules/system";
|
|
58
60
|
export type { TranscriptionConfig, TranscriptionOptions } from "../modules/transcription";
|
|
59
61
|
export type { PermissionErrorEvent } from "../modules/permissions";
|
|
60
|
-
export type { AuthUpdatePayload, MiniappVisibility, PermissionType, PermissionRecord, GlassesCapabilities, ConnectAckPayload, MiniappAuthState, MiniappRequestError, } from "../session";
|
|
62
|
+
export type { AuthUpdatePayload, MiniappLaunchSource, MiniappVisibility, PermissionType, PermissionRecord, GlassesCapabilities, ConnectAckPayload, MiniappAuthState, MiniappRequestError, } from "../session";
|
|
61
63
|
export type { AuthFetchOptions, AuthModule } from "../modules/auth";
|
|
62
64
|
export type { MiniappColorScheme } from "../globals";
|
|
63
65
|
export type { LatLng, TravelMode, ManeuverKind, RouteAvoidances, NavManeuver, NavOffRoute, NavRerouting, NavArrived, NavError, NavCancelled, NavUpdate, NavRoute, PivotOptions, Pivot, PivotEvent, NavStep, NavigationDev, StartNavigationOptions, NavState, NavPermissionResult, ComputeRouteOptions, ComputedRouteStep, ComputedRoute, ComputeRouteResult, } from "../modules/navigation";
|
|
66
|
+
export type { LightSensorModule, LightSensorOptions, LightSensorData } from "../modules/lightSensor";
|
|
67
|
+
export type { CompassModule, CompassOptions, CompassData, CompassDiagnostics, CompassCalibrationData, } from "../modules/compass";
|
|
68
|
+
export type { MirrorModule } from "../modules/mirror";
|
|
69
|
+
export type { MirrorSnapshot, MirrorContent, MirrorElement } from "../mirror/types";
|
|
64
70
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/background/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,cAAc,EAAE,KAAK,qBAAqB,EAAC,MAAM,YAAY,CAAA;AACrE,OAAO,EAAC,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAC,MAAM,YAAY,CAAA;AAI7F,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,EACP,WAAW,EACX,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,SAAS,EACT,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAC,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAC,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/background/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,cAAc,EAAE,KAAK,qBAAqB,EAAC,MAAM,YAAY,CAAA;AACrE,OAAO,EAAC,eAAe,EAAE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAC,MAAM,YAAY,CAAA;AAI7F,OAAO,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAA;AAExE,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,cAAc,EACd,OAAO,EACP,WAAW,EACX,cAAc,EACd,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAC,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,kBAAkB,CAAA;AAIjH,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,aAAa,CAAA;AACxG,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAC,YAAY,EAAE,qBAAqB,EAAC,MAAM,sBAAsB,CAAA;AAK7E,YAAY,EAAC,aAAa,EAAE,aAAa,EAAE,aAAa,EAAC,MAAM,oBAAoB,CAAA;AAInF,YAAY,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAA;AACtD,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,yBAAyB,EACzB,2BAA2B,EAC3B,iBAAiB,EACjB,WAAW,GACZ,MAAM,kBAAkB,CAAA;AACzB,YAAY,EAAC,YAAY,EAAC,MAAM,sBAAsB,CAAA;AACtD,YAAY,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,kBAAkB,CAAA;AACrE,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AACvD,YAAY,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,aAAa,GACd,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAA;AACvD,YAAY,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAA;AAC7C,YAAY,EAAC,gBAAgB,EAAC,MAAM,uBAAuB,CAAA;AAC3D,YAAY,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAA;AAC7D,YAAY,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,kBAAkB,CAAA;AACrE,YAAY,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,qBAAqB,CAAA;AACvE,YAAY,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,sBAAsB,EAAE,uBAAuB,EAAC,MAAM,iBAAiB,CAAA;AACnH,YAAY,EAAC,QAAQ,EAAE,cAAc,EAAE,qBAAqB,EAAE,iBAAiB,EAAC,MAAM,iBAAiB,CAAA;AACvG,OAAO,EAAC,aAAa,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAA;AAC9D,YAAY,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAA;AACrD,YAAY,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAC,mBAAmB,EAAC,MAAM,0BAA0B,CAAA;AACjE,YAAY,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAA;AAC7D,YAAY,EAAC,QAAQ,EAAE,gBAAgB,EAAE,aAAa,EAAC,MAAM,eAAe,CAAA;AAC5E,YAAY,EAAC,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,eAAe,CAAA;AACnG,OAAO,EAAC,QAAQ,EAAE,eAAe,EAAC,MAAM,eAAe,CAAA;AAQvD,YAAY,EAAC,QAAQ,EAAE,iBAAiB,EAAC,MAAM,gBAAgB,CAAA;AAC/D,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,eAAe,GAChB,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAC,aAAa,EAAE,yBAAyB,EAAC,MAAM,sBAAsB,CAAA;AAClF,YAAY,EAAC,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAC,MAAM,oBAAoB,CAAA;AACpH,YAAY,EACV,YAAY,EACZ,WAAW,EACX,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAC,mBAAmB,EAAE,oBAAoB,EAAC,MAAM,0BAA0B,CAAA;AACvF,YAAY,EAAC,oBAAoB,EAAC,MAAM,wBAAwB,CAAA;AAChE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAC,gBAAgB,EAAE,UAAU,EAAC,MAAM,iBAAiB,CAAA;AACjE,YAAY,EAAC,kBAAkB,EAAC,MAAM,YAAY,CAAA;AAElD,YAAY,EACV,MAAM,EACN,UAAU,EACV,YAAY,EACZ,eAAe,EACf,WAAW,EACX,WAAW,EACX,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,UAAU,EACV,OAAO,EACP,aAAa,EACb,sBAAsB,EACtB,QAAQ,EACR,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,GACnB,MAAM,uBAAuB,CAAA;AAE9B,YAAY,EAAC,iBAAiB,EAAE,kBAAkB,EAAE,eAAe,EAAC,MAAM,wBAAwB,CAAA;AAClG,YAAY,EACV,aAAa,EACb,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAA;AACnD,YAAY,EAAC,cAAc,EAAE,aAAa,EAAE,aAAa,EAAC,MAAM,iBAAiB,CAAA"}
|
package/dist/background/index.js
CHANGED
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export { MiniappSession } from "../session";
|
|
18
18
|
export { registerMiniapp } from "./register";
|
|
19
|
+
// Event / data type re-exports — these are payload shapes a miniapp's
|
|
20
|
+
// background-side handlers consume from session.transcription.on, etc.
|
|
21
|
+
export { monoTextRows } from "../modules/mono-text-rows";
|
|
22
|
+
export { LatestRenderScheduler } from "../modules/latest-render-scheduler";
|
|
19
23
|
// Public envelope + protocol types so authors can write strongly-typed
|
|
20
24
|
// glue when they need to fall back to session.sendOneShot / sendRequest.
|
|
21
25
|
export { MiniappRequestType, MiniappResponseType, MiniappStreamType, MiniappErrorCode } from "../protocol";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/background/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,cAAc,EAA6B,MAAM,YAAY,CAAA;AACrE,OAAO,EAAC,eAAe,EAAoD,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/background/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAC,cAAc,EAA6B,MAAM,YAAY,CAAA;AACrE,OAAO,EAAC,eAAe,EAAoD,MAAM,YAAY,CAAA;AAE7F,sEAAsE;AACtE,uEAAuE;AACvE,OAAO,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAA;AACtD,OAAO,EAAC,qBAAqB,EAAC,MAAM,oCAAoC,CAAA;AAuBxE,uEAAuE;AACvE,yEAAyE;AACzE,OAAO,EAAC,kBAAkB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAC,MAAM,aAAa,CAAA;AACxG,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,sBAAsB,CAAA;AA+C7B,OAAO,EAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,sBAAsB,EAAE,uBAAuB,EAAC,MAAM,iBAAiB,CAAA;AAEnH,OAAO,EAAC,aAAa,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAA;AAQ9D,OAAO,EAAC,QAAQ,EAAE,eAAe,EAAC,MAAM,eAAe,CAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* registerMiniapp — entry hook for the background JSContext.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
4
|
+
* The JSRuntime host loads the polyfill (which installs __dispatch /
|
|
5
5
|
* __deliver / timers / fetch / etc.), then evaluates the miniapp's
|
|
6
6
|
* background bundle. After both scripts have evaluated successfully,
|
|
7
7
|
* the host delivers a single `{kind: "init", sessionId}` envelope.
|