Skip to content

Commit 9971afe

Browse files
authored
Merge pull request #157 from hyperware-ai/hf/move-hyperapp-here
move hyperapp here
2 parents 13a4bda + 753dac3 commit 9971afe

22 files changed

+2796
-616
lines changed

Cargo.lock

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ repository = "https://github.com/hyperware-ai/process_lib"
99
license = "Apache-2.0"
1010

1111
[features]
12+
hyperapp = ["dep:futures-util", "dep:uuid", "logging"]
1213
logging = ["dep:color-eyre", "dep:tracing", "dep:tracing-error", "dep:tracing-subscriber"]
1314
hyperwallet = []
1415
simulation-mode = []
@@ -29,19 +30,21 @@ alloy = { version = "0.8.1", features = [
2930
anyhow = "1.0"
3031
base64 = "0.22.1"
3132
bincode = "1.3.3"
32-
color-eyre = { version = "0.6", features = ["capture-spantrace"], optional = true }
33-
hex = "0.4.3"
3433
http = "1.0.0"
3534
mime_guess = "2.0"
3635
rand = "0.8"
3736
regex = "1.11.1"
3837
rmp-serde = "1.1.2"
3938
serde = { version = "1.0", features = ["derive"] }
4039
serde_json = "1.0.120"
41-
sha3 = "0.10.8"
4240
thiserror = "1.0"
41+
url = "2.4.1"
42+
wit-bindgen = "0.42.1"
43+
44+
futures-util = { version = "0.3", optional = true }
45+
uuid = { version = "1.0", features = ["v4"], optional = true }
46+
47+
color-eyre = { version = "0.6", features = ["capture-spantrace"], optional = true }
4348
tracing = { version = "0.1", optional = true }
4449
tracing-error = { version = "0.2", optional = true }
4550
tracing-subscriber = { version = "0.3", features = ["env-filter", "json", "std"], optional = true }
46-
url = "2.4.1"
47-
wit-bindgen = "0.42.1"

src/http/client.rs

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
pub use super::server::{HttpResponse, WsMessageType};
2-
use crate::{get_blob, LazyLoadBlob as KiBlob, Message, Request as KiRequest};
2+
#[cfg(not(feature = "hyperapp"))]
3+
use crate::Message;
4+
use crate::{get_blob, LazyLoadBlob as KiBlob, Request as KiRequest};
35
use http::Method;
46
use serde::{Deserialize, Serialize};
57
use std::collections::HashMap;
68
use std::str::FromStr;
79
use thiserror::Error;
810

11+
#[cfg(feature = "hyperapp")]
12+
use crate::hyperapp;
13+
914
/// [`crate::Request`] type sent to the `http-client:distro:sys` service in order to open a
1015
/// WebSocket connection, send a WebSocket message on an existing connection, or
1116
/// send an HTTP request.
@@ -131,6 +136,7 @@ pub fn send_request(
131136
/// Make an HTTP request using http-client and await its response.
132137
///
133138
/// Returns HTTP response from the `http` crate if successful, with the body type as bytes.
139+
#[cfg(not(feature = "hyperapp"))]
134140
pub fn send_request_await_response(
135141
method: Method,
136142
url: url::Url,
@@ -190,6 +196,64 @@ pub fn send_request_await_response(
190196
.unwrap())
191197
}
192198

199+
/// Make an HTTP request using http-client and await its response.
200+
///
201+
/// Returns HTTP response from the `http` crate if successful, with the body type as bytes.
202+
#[cfg(feature = "hyperapp")]
203+
pub async fn send_request_await_response(
204+
method: Method,
205+
url: url::Url,
206+
headers: Option<HashMap<String, String>>,
207+
timeout: u64,
208+
body: Vec<u8>,
209+
) -> std::result::Result<http::Response<Vec<u8>>, HttpClientError> {
210+
let request = KiRequest::to(("our", "http-client", "distro", "sys"))
211+
.body(
212+
serde_json::to_vec(&HttpClientAction::Http(OutgoingHttpRequest {
213+
method: method.to_string(),
214+
version: None,
215+
url: url.to_string(),
216+
headers: headers.unwrap_or_default(),
217+
}))
218+
.map_err(|_| HttpClientError::MalformedRequest)?,
219+
)
220+
.blob_bytes(body)
221+
.expects_response(timeout);
222+
223+
let resp_result =
224+
hyperapp::send::<std::result::Result<HttpClientResponse, HttpClientError>>(request)
225+
.await
226+
.map_err(|_| {
227+
HttpClientError::ExecuteRequestFailed("http-client timed out".to_string())
228+
})?;
229+
230+
let resp = match resp_result {
231+
Ok(HttpClientResponse::Http(resp)) => resp,
232+
Ok(HttpClientResponse::WebSocketAck) => {
233+
return Err(HttpClientError::ExecuteRequestFailed(
234+
"http-client gave unexpected response".to_string(),
235+
))
236+
}
237+
Err(e) => return Err(e),
238+
};
239+
let mut http_response = http::Response::builder()
240+
.status(http::StatusCode::from_u16(resp.status).unwrap_or_default());
241+
let headers = http_response.headers_mut().unwrap();
242+
for (key, value) in &resp.headers {
243+
let Ok(key) = http::header::HeaderName::from_str(key) else {
244+
continue;
245+
};
246+
let Ok(value) = http::header::HeaderValue::from_str(value) else {
247+
continue;
248+
};
249+
headers.insert(key, value);
250+
}
251+
Ok(http_response
252+
.body(get_blob().unwrap_or_default().bytes)
253+
.unwrap())
254+
}
255+
256+
#[cfg(not(feature = "hyperapp"))]
193257
pub fn open_ws_connection(
194258
url: String,
195259
headers: Option<HashMap<String, String>>,
@@ -231,7 +295,37 @@ pub fn send_ws_client_push(channel_id: u32, message_type: WsMessageType, blob: K
231295
.unwrap()
232296
}
233297

298+
#[cfg(feature = "hyperapp")]
299+
pub async fn open_ws_connection(
300+
url: String,
301+
headers: Option<HashMap<String, String>>,
302+
channel_id: u32,
303+
) -> std::result::Result<(), HttpClientError> {
304+
let request = KiRequest::to(("our", "http-client", "distro", "sys"))
305+
.body(
306+
serde_json::to_vec(&HttpClientAction::WebSocketOpen {
307+
url: url.clone(),
308+
headers: headers.unwrap_or(HashMap::new()),
309+
channel_id,
310+
})
311+
.unwrap(),
312+
)
313+
.expects_response(5);
314+
315+
let resp_result =
316+
hyperapp::send::<std::result::Result<HttpClientResponse, HttpClientError>>(request)
317+
.await
318+
.map_err(|_| HttpClientError::WsOpenFailed { url: url.clone() })?;
319+
320+
match resp_result {
321+
Ok(HttpClientResponse::WebSocketAck) => Ok(()),
322+
Err(e) => Err(e),
323+
_ => Err(HttpClientError::WsOpenFailed { url }),
324+
}
325+
}
326+
234327
/// Close a WebSocket connection.
328+
#[cfg(not(feature = "hyperapp"))]
235329
pub fn close_ws_connection(channel_id: u32) -> std::result::Result<(), HttpClientError> {
236330
let Ok(Ok(Message::Response { body, .. })) =
237331
KiRequest::to(("our", "http-client", "distro", "sys"))
@@ -251,3 +345,27 @@ pub fn close_ws_connection(channel_id: u32) -> std::result::Result<(), HttpClien
251345
_ => Err(HttpClientError::WsCloseFailed { channel_id }),
252346
}
253347
}
348+
349+
/// Close a WebSocket connection.
350+
#[cfg(feature = "hyperapp")]
351+
pub async fn close_ws_connection(channel_id: u32) -> std::result::Result<(), HttpClientError> {
352+
let request = KiRequest::to(("our", "http-client", "distro", "sys"))
353+
.body(
354+
serde_json::json!(HttpClientAction::WebSocketClose { channel_id })
355+
.to_string()
356+
.as_bytes()
357+
.to_vec(),
358+
)
359+
.expects_response(5);
360+
361+
let resp_result =
362+
hyperapp::send::<std::result::Result<HttpClientResponse, HttpClientError>>(request)
363+
.await
364+
.map_err(|_| HttpClientError::WsCloseFailed { channel_id })?;
365+
366+
match resp_result {
367+
Ok(HttpClientResponse::WebSocketAck) => Ok(()),
368+
Err(e) => Err(e),
369+
_ => Err(HttpClientError::WsCloseFailed { channel_id }),
370+
}
371+
}

0 commit comments

Comments
 (0)