feat: cut over rust web main shell
This commit is contained in:
@@ -2,10 +2,12 @@ use crate::app::AppState;
|
||||
use crate::context::RequestContext;
|
||||
use crate::error::WebError;
|
||||
use crate::routes::stream_support::{
|
||||
StreamChangeKind, StreamSnapshotQuery, build_stream_delta_payload, load_stream_overview,
|
||||
load_stream_snapshot, read_stream_cursor_from_payload, resolve_stream_change, with_stream_kind,
|
||||
build_stream_delta_payload, load_stream_overview, load_stream_snapshot,
|
||||
read_stream_cursor_from_payload, resolve_stream_change, with_stream_kind, StreamChangeKind,
|
||||
StreamSnapshotQuery,
|
||||
};
|
||||
use axum::extract::{Extension, Query, State};
|
||||
use axum::http::{HeaderMap, HeaderName, HeaderValue};
|
||||
use axum::response::sse::{Event, KeepAlive, Sse};
|
||||
use futures_util::stream;
|
||||
use serde_json::Value;
|
||||
@@ -117,6 +119,28 @@ pub async fn events(
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn tree_events(
|
||||
State(state): State<AppState>,
|
||||
Extension(context): Extension<RequestContext>,
|
||||
Query(query): Query<StreamSnapshotQuery>,
|
||||
) -> Result<
|
||||
(
|
||||
HeaderMap,
|
||||
Sse<impl futures_util::Stream<Item = Result<Event, Infallible>>>,
|
||||
),
|
||||
WebError,
|
||||
> {
|
||||
let mut headers = HeaderMap::new();
|
||||
if let Ok(name) = HeaderName::from_lowercase(b"x-mnote-web-owner") {
|
||||
headers.insert(name, HeaderValue::from_static("mnote-web"));
|
||||
}
|
||||
if let Ok(name) = HeaderName::from_lowercase(b"x-mnote-tree-stream-owner") {
|
||||
headers.insert(name, HeaderValue::from_static("rust-web"));
|
||||
}
|
||||
let sse = events(State(state), Extension(context), Query(query)).await?;
|
||||
Ok((headers, sse))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct StreamPollState {
|
||||
app_state: AppState,
|
||||
@@ -137,8 +161,8 @@ fn stream_event(event_name: &str, payload: &Value) -> Event {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::app::{AppConfig, AppState, build_app};
|
||||
use axum::body::{Body, to_bytes};
|
||||
use crate::app::{build_app, AppConfig, AppState};
|
||||
use axum::body::{to_bytes, Body};
|
||||
use axum::http::{Request, StatusCode};
|
||||
use tower::util::ServiceExt;
|
||||
|
||||
@@ -147,6 +171,9 @@ mod tests {
|
||||
service_name: "mnote-web".into(),
|
||||
service_version: "0.1.0".into(),
|
||||
bind_addr: "127.0.0.1:0".into(),
|
||||
public_bind_addr: "127.0.0.1:3000".into(),
|
||||
legacy_next_base_url: Some("http://127.0.0.1:3100".into()),
|
||||
enable_legacy_next_compat: true,
|
||||
enable_debug_shell_routes: false,
|
||||
hermes_base_path: "/api/hermes".into(),
|
||||
compat_next_base_path: "/api/compat/next".into(),
|
||||
@@ -183,4 +210,39 @@ mod tests {
|
||||
assert!(text.contains("\"projection\":\"sidebar_tree\""));
|
||||
assert!(text.contains("\"workspaceId\":\"ws_demo\""));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn tree_realtime_route_returns_rust_web_owned_snapshot_event() {
|
||||
let response = app()
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.uri("/api/tree/events?workspaceId=ws_demo&maxPolls=0")
|
||||
.body(Body::empty())
|
||||
.expect("request"),
|
||||
)
|
||||
.await
|
||||
.expect("response");
|
||||
|
||||
assert_eq!(response.status(), StatusCode::OK);
|
||||
assert_eq!(
|
||||
response
|
||||
.headers()
|
||||
.get("x-mnote-web-owner")
|
||||
.and_then(|value| value.to_str().ok()),
|
||||
Some("mnote-web")
|
||||
);
|
||||
assert_eq!(
|
||||
response
|
||||
.headers()
|
||||
.get("x-mnote-tree-stream-owner")
|
||||
.and_then(|value| value.to_str().ok()),
|
||||
Some("rust-web")
|
||||
);
|
||||
let body = to_bytes(response.into_body(), usize::MAX)
|
||||
.await
|
||||
.expect("body");
|
||||
let text = String::from_utf8(body.to_vec()).expect("utf8");
|
||||
assert!(text.contains("event: snapshot") || text.contains("event:snapshot"));
|
||||
assert!(text.contains("\"kind\":\"snapshot\""));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user