use crate::cdp::session::CdpSession;
use crate::error::{Error, Result};
use serde::de::DeserializeOwned;
use serde_json::{json, Value};
use std::sync::Arc;
#[derive(Clone)]
pub struct Worker {
inner: Arc<WorkerInner>,
}
struct WorkerInner {
url: String,
session: CdpSession,
}
impl Worker {
pub(crate) fn new(connection: Arc<crate::cdp::connection::CdpConnection>, session_id: String, url: String) -> Self {
let session = CdpSession::target(connection, session_id);
Self {
inner: Arc::new(WorkerInner { url, session }),
}
}
pub fn url(&self) -> &str {
&self.inner.url
}
#[allow(dead_code)]
pub(crate) fn session(&self) -> &CdpSession {
&self.inner.session
}
pub(crate) async fn enable_runtime(&self) {
let _ = self.inner.session.send("Runtime.enable", json!({})).await;
}
pub async fn evaluate<R: DeserializeOwned>(&self, expression: &str) -> Result<R> {
let wrapped = format!("(() => {{ return ({expression}); }})()");
let resp = self
.inner
.session
.send(
"Runtime.evaluate",
json!({
"expression": wrapped,
"returnByValue": true,
"awaitPromise": true,
}),
)
.await?;
if let Some(exc) = resp.get("exceptionDetails") {
let msg = exc
.get("exception")
.and_then(|e| e.get("description"))
.and_then(|v| v.as_str())
.unwrap_or("evaluation threw");
return Err(Error::ProtocolError(format!("eval error: {msg}")));
}
let value = resp
.get("result")
.and_then(|r| r.get("value"))
.cloned()
.unwrap_or(Value::Null);
serde_json::from_value::<R>(value).map_err(Error::from)
}
}