From 500ddc2a8ac5b2e2676dc2c80410dd40229bd1f0 Mon Sep 17 00:00:00 2001 From: Steven Enamakel <31011319+senamakel@users.noreply.github.com> Date: Thu, 23 Apr 2026 22:21:53 -0700 Subject: [PATCH] feat(webview_apis): WebSocket bridge for live-webview APIs, Gmail first (#869) --- app/src-tauri/Cargo.lock | 1 + app/src-tauri/Cargo.toml | 17 +- app/src-tauri/src/cdp/mod.rs | 2 +- app/src-tauri/src/gmail/atom.rs | 315 +++++++++++++ app/src-tauri/src/gmail/cdp_fetch.rs | 150 +++++++ app/src-tauri/src/gmail/mod.rs | 240 ++++++++++ app/src-tauri/src/gmail/print_view.rs | 538 +++++++++++++++++++++++ app/src-tauri/src/gmail/reads.rs | 302 +++++++++++++ app/src-tauri/src/gmail/session.rs | 83 ++++ app/src-tauri/src/gmail/types.rs | 77 ++++ app/src-tauri/src/gmail/writes.rs | 36 ++ app/src-tauri/src/lib.rs | 91 ++++ app/src-tauri/src/webview_apis/mod.rs | 39 ++ app/src-tauri/src/webview_apis/router.rs | 176 ++++++++ app/src-tauri/src/webview_apis/server.rs | 236 ++++++++++ scripts/mock-webview-bridge.mjs | 48 ++ src/core/all.rs | 7 + src/openhuman/mod.rs | 1 + src/openhuman/webview_apis/client.rs | 239 ++++++++++ src/openhuman/webview_apis/mod.rs | 24 + src/openhuman/webview_apis/rpc.rs | 173 ++++++++ src/openhuman/webview_apis/schemas.rs | 253 +++++++++++ src/openhuman/webview_apis/types.rs | 55 +++ tests/webview_apis_bridge.rs | 124 ++++++ 24 files changed, 3222 insertions(+), 5 deletions(-) create mode 100644 app/src-tauri/src/gmail/atom.rs create mode 100644 app/src-tauri/src/gmail/cdp_fetch.rs create mode 100644 app/src-tauri/src/gmail/mod.rs create mode 100644 app/src-tauri/src/gmail/print_view.rs create mode 100644 app/src-tauri/src/gmail/reads.rs create mode 100644 app/src-tauri/src/gmail/session.rs create mode 100644 app/src-tauri/src/gmail/types.rs create mode 100644 app/src-tauri/src/gmail/writes.rs create mode 100644 app/src-tauri/src/webview_apis/mod.rs create mode 100644 app/src-tauri/src/webview_apis/router.rs create mode 100644 app/src-tauri/src/webview_apis/server.rs create mode 100644 scripts/mock-webview-bridge.mjs create mode 100644 src/openhuman/webview_apis/client.rs create mode 100644 src/openhuman/webview_apis/mod.rs create mode 100644 src/openhuman/webview_apis/rpc.rs create mode 100644 src/openhuman/webview_apis/schemas.rs create mode 100644 src/openhuman/webview_apis/types.rs create mode 100644 tests/webview_apis_bridge.rs diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index 9063edd1b..90824953b 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -8,6 +8,7 @@ version = "0.52.28" dependencies = [ "anyhow", "async-trait", + "base64 0.22.1", "cef", "chrono", "env_logger", diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 11d0d0dbb..dff5effcb 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -48,11 +48,20 @@ tauri-plugin-notification = { path = "vendor/tauri-plugin-notification" } tauri-plugin-opener = "2" serde = { version = "1", features = ["derive"] } serde_json = "1" +# Used by gmail/cdp_fetch for decoding binary IO.read chunks. Base64 is +# only emitted by CDP IO.read when the stream contains non-UTF-8 bytes, +# but we opt into the feature to stay robust against unexpected responses. +base64 = "0.22" tokio = { version = "1", features = ["rt-multi-thread", "process", "sync", "time", "net"] } -# WebSocket client for the Chrome DevTools Protocol (used to talk to the -# embedded CEF instance over `--remote-debugging-port=9222` and read -# IndexedDB / drive `Runtime.evaluate` for the WhatsApp recipe). -tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect"] } +# WebSocket client + server for two uses: +# - Client: Chrome DevTools Protocol connections to the embedded CEF +# instance over `--remote-debugging-port=9222` (IndexedDB reads, +# `Runtime.evaluate` for the WhatsApp recipe, DOMSnapshot / Network +# calls for the Gmail connector). +# - Server: the `webview_apis` bridge at 127.0.0.1 that accepts +# JSON-RPC frames from the core sidecar so core-side handlers can +# reach the live-webview connectors via CDP. +tokio-tungstenite = { version = "0.24", default-features = false, features = ["connect", "handshake"] } futures-util = { version = "0.3", default-features = false, features = ["sink", "std"] } reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } diff --git a/app/src-tauri/src/cdp/mod.rs b/app/src-tauri/src/cdp/mod.rs index c227651c9..94efe1123 100644 --- a/app/src-tauri/src/cdp/mod.rs +++ b/app/src-tauri/src/cdp/mod.rs @@ -16,7 +16,7 @@ pub mod target; pub use conn::CdpConn; pub use emulation::{set_user_agent_override, UaSpec}; -pub use session::{placeholder_data_url, spawn_session, target_url_fragment}; +pub use session::{placeholder_data_url, placeholder_marker, spawn_session, target_url_fragment}; pub use snapshot::Snapshot; pub use target::{ browser_ws_url, connect_and_attach_matching, detach_session, find_page_target_where, diff --git a/app/src-tauri/src/gmail/atom.rs b/app/src-tauri/src/gmail/atom.rs new file mode 100644 index 000000000..e398dcb67 --- /dev/null +++ b/app/src-tauri/src/gmail/atom.rs @@ -0,0 +1,315 @@ +//! Gmail Atom feed parser. +//! +//! Gmail exposes a stable Atom feed at +//! `https://mail.google.com/mail/u/0/feed/atom[/