Skip to main content

lingxia_devtool_protocol/
lib.rs

1use serde::{Deserialize, Serialize};
2
3pub mod handlers {
4    pub const ECHO: &str = "echo";
5
6    pub mod browser {
7        pub const OPEN: &str = "browser.open";
8        pub const TABS: &str = "browser.tabs";
9        pub const CURRENT: &str = "browser.current";
10        pub const ACTIVATE: &str = "browser.activate";
11        pub const CLOSE: &str = "browser.close";
12        pub const RELOAD: &str = "browser.reload";
13        pub const BACK: &str = "browser.back";
14        pub const FORWARD: &str = "browser.forward";
15        pub const EVAL: &str = "browser.eval";
16        pub const QUERY: &str = "browser.query";
17        pub const WAIT: &str = "browser.wait";
18        pub const WAIT_URL: &str = "browser.wait_url";
19        pub const WAIT_NAVIGATION: &str = "browser.wait_navigation";
20        pub const CLICK: &str = "browser.click";
21        pub const TYPE: &str = "browser.type";
22        pub const FILL: &str = "browser.fill";
23        pub const PRESS: &str = "browser.press";
24        pub const SCROLL: &str = "browser.scroll";
25        pub const SCROLL_TO: &str = "browser.scroll_to";
26        pub const COOKIES_LIST: &str = "browser.cookies.list";
27        pub const COOKIES_SET: &str = "browser.cookies.set";
28        pub const COOKIES_DELETE: &str = "browser.cookies.delete";
29        pub const COOKIES_CLEAR: &str = "browser.cookies.clear";
30        pub const SCREENSHOT: &str = "browser.screenshot";
31    }
32
33    pub mod lxapp {
34        pub const LIST: &str = "lxapp.list";
35        pub const CURRENT: &str = "lxapp.current";
36        pub const INFO: &str = "lxapp.info";
37        pub const PAGES: &str = "lxapp.pages";
38        pub const EVAL: &str = "lxapp.eval";
39        pub const OPEN: &str = "lxapp.open";
40        pub const CLOSE: &str = "lxapp.close";
41        pub const RESTART: &str = "lxapp.restart";
42        pub const UNINSTALL: &str = "lxapp.uninstall";
43        /// Build the lxapp front-end bundle. Handled by the `lingxia dev`
44        /// orchestrator (which owns the project + build pipeline), not the
45        /// runtime — so it works even with no app attached.
46        pub const BUILD: &str = "lxapp.build";
47    }
48
49    pub mod lxapp_nav {
50        pub const TO: &str = "lxapp.nav.to";
51        pub const REDIRECT: &str = "lxapp.nav.redirect";
52        pub const SWITCH_TAB: &str = "lxapp.nav.switch_tab";
53        pub const RELAUNCH: &str = "lxapp.nav.relaunch";
54        pub const BACK: &str = "lxapp.nav.back";
55    }
56
57    pub mod app {
58        /// Capture a PNG of the host app's window. Accepts an optional
59        /// `window_id` (returned by [`WINDOWS`]) so multi-window desktop
60        /// apps can pick a specific surface; mobile platforms ignore it
61        /// since they have a single foreground window. Returns a JSON
62        /// envelope `{format, size_bytes, data_base64}`.
63        pub const SCREENSHOT: &str = "app.screenshot";
64
65        /// Enumerate the host app's top-level windows. Returns a JSON
66        /// array of `{id, title, focused, main, visible, width, height}`.
67        pub const WINDOWS: &str = "app.windows";
68
69        /// Dispatch mouse input to a host app window. Accepts
70        /// `{window_id?, action}` where action is a tagged object such as
71        /// `{kind:"click", x, y, button?}`.
72        pub const MOUSE: &str = "app.mouse";
73    }
74
75    pub mod lxapp_page {
76        pub const CURRENT: &str = "lxapp.page.current";
77        pub const LIST: &str = "lxapp.page.list";
78        pub const INFO: &str = "lxapp.page.info";
79        pub const EVAL: &str = "lxapp.page.eval";
80        pub const QUERY: &str = "lxapp.page.query";
81        pub const CLICK: &str = "lxapp.page.click";
82        pub const TYPE: &str = "lxapp.page.type";
83        pub const FILL: &str = "lxapp.page.fill";
84        pub const PRESS: &str = "lxapp.page.press";
85        pub const BACK: &str = "lxapp.page.back";
86        pub const SCREENSHOT: &str = "lxapp.page.screenshot";
87    }
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
91#[serde(rename_all = "snake_case")]
92pub enum DevtoolsPeerRole {
93    Devtool,
94    Client,
95}
96
97#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
98#[serde(rename_all = "snake_case")]
99pub enum DevtoolsLogLevel {
100    Verbose,
101    Debug,
102    Info,
103    Warn,
104    Error,
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
108#[serde(rename_all = "snake_case")]
109pub enum DevtoolsLogSource {
110    Native,
111    WebViewConsole,
112    LxAppServiceConsole,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub struct DevtoolsLogMessage {
117    pub timestamp_ms: u64,
118    #[serde(alias = "tag")]
119    pub source: DevtoolsLogSource,
120    pub level: DevtoolsLogLevel,
121    pub appid: Option<String>,
122    pub path: Option<String>,
123    pub message: String,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
127#[serde(tag = "type", rename_all = "snake_case")]
128pub enum DevtoolsWireMessage {
129    Hello {
130        role: DevtoolsPeerRole,
131    },
132    LogBatch {
133        logs: Vec<DevtoolsLogMessage>,
134    },
135    Command {
136        command_id: String,
137        handler: String,
138        #[serde(default, skip_serializing_if = "Option::is_none")]
139        args: Option<serde_json::Value>,
140    },
141    Result {
142        command_id: String,
143        ok: bool,
144        #[serde(default, skip_serializing_if = "Option::is_none")]
145        data: Option<serde_json::Value>,
146        #[serde(default, skip_serializing_if = "Option::is_none")]
147        error: Option<String>,
148    },
149}