Skip to main content

host_extensions/
trait_def.rs

1#[derive(Debug, Clone, PartialEq, Eq)]
2pub struct HostPushEvent {
3    pub event: String,
4    pub payload_json: String,
5}
6
7/// A host extension contributes a JS injection script and a message handler.
8///
9/// Extensions register as `window.host.ext.<namespace>` in the SPA WebView.
10/// Each extension gets its own WKScriptMessageHandler channel, its own
11/// pending-promise map, and its own resolve/push callbacks — fully independent
12/// of the core `window.host` bridge.
13pub trait HostExtension: Send + Sync + 'static {
14    /// Sub-namespace under `window.host.ext.*` (e.g. "data" → `window.host.ext.data`)
15    fn namespace(&self) -> &str;
16
17    /// WKScriptMessageHandler channel name (e.g. "hostDataBridge")
18    fn channel(&self) -> &str;
19
20    /// JavaScript injected after HOST_API_SCRIPT. Must:
21    /// 1. Define its own `_call` function using its own message handler channel
22    /// 2. Define `window.__host{Name}Resolve` for response resolution
23    /// 3. Define `window.__host{Name}Push` for push events
24    /// 4. Set `window.host.ext.<namespace> = Object.freeze({...})`
25    fn inject_script(&self) -> &str;
26
27    /// Handle a message from the JS bridge.
28    /// `method` is the method name from the JS _call.
29    /// `params` is the JSON params object as a string.
30    /// Returns a serialized JSON result, or None for fire-and-forget.
31    fn handle_message(&self, method: &str, params: &str) -> Option<String>;
32
33    /// Drain queued push events destined for `window.host.on(...)` listeners.
34    ///
35    /// The returned payload is the canonical JSON string for the event's shared
36    /// Rust/TypeScript payload shape.
37    fn drain_events(&self) -> Vec<HostPushEvent> {
38        Vec::new()
39    }
40}