Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

event kind and op

running a little ahead of what actually exists but there's a chance to minimize breaking the api. it will probably break anyway but hey.

Changed files
+26 -10
spacedust
+12 -7
spacedust/src/lib.rs
···
}
#[derive(Debug, Serialize)]
-
struct ClientEvent {
+
struct ClientLinkEvent {
+
operation: String,
source: String,
-
origin: String,
-
target: String,
+
source_record: String,
+
subject: String,
// TODO: include the record too? would save clients a level of hydration
}
-
impl From<LinkEvent> for ClientEvent {
+
impl From<LinkEvent> for ClientLinkEvent {
fn from(link: LinkEvent) -> Self {
-
let undotted = link.path.get(1..).unwrap_or("");
+
let undotted = link.path.strip_prefix('.').unwrap_or_else(|| {
+
eprintln!("link path did not have expected '.' prefix: {}", link.path);
+
""
+
});
Self {
+
operation: "create".to_string(),
source: format!("{}:{undotted}", link.collection),
-
origin: link.origin,
-
target: link.target,
+
source_record: link.origin,
+
subject: link.target,
}
}
}
+14 -3
spacedust/src/server.rs
···
-
use crate::{ClientEvent, LinkEvent};
+
use crate::{ClientLinkEvent, LinkEvent};
use dropshot::{
ApiDescription, ConfigDropshot, ConfigLogging, ConfigLoggingLevel, Query, RequestContext,
ServerBuilder, WebsocketConnection, channel,
};
use futures::SinkExt;
use schemars::JsonSchema;
-
use serde::Deserialize;
+
use serde::{Deserialize, Serialize};
use tokio::sync::broadcast;
use tokio_tungstenite::tungstenite::Message;
use tokio_tungstenite::tungstenite::protocol::Role;
···
server.await
}
+
#[derive(Debug, Serialize)]
+
#[serde(rename_all="snake_case")]
+
struct ClientEvent {
+
r#type: String,
+
link: ClientLinkEvent,
+
}
+
#[derive(Deserialize, JsonSchema)]
struct QueryParams {
_hello: Option<String>,
···
loop {
match sub.recv().await {
Ok(link) => {
-
let json = serde_json::to_string::<ClientEvent>(&link.into())?;
+
let ev = ClientEvent {
+
r#type: "link".to_string(),
+
link: link.into(),
+
};
+
let json = serde_json::to_string(&ev)?;
if let Err(e) = ws.send(Message::Text(json.into())).await {
eprintln!("client: failed to send event: {e:?}");
ws.close(None).await?; // TODO: do we need this one??