Skip to main content

host_ext_api/
lib.rs

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