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}