Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 46 additions & 21 deletions src/streaming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,39 +91,54 @@ fn ws_config() -> WebSocketConfig {

// --- Event payloads ---

#[derive(Debug, Clone, Serialize)]
/// `stream-status` で報告する接続状態 (#781)。
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "lowercase")]
pub enum StreamConnectionState {
Connected,
Reconnecting,
Disconnected,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamNoteEvent {
pub account_id: String,
pub subscription_id: String,
pub note: Arc<NormalizedNote>,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamNotificationEvent {
pub account_id: String,
pub subscription_id: String,
pub notification: NormalizedNotification,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamMentionEvent {
pub account_id: String,
pub subscription_id: String,
pub note: Arc<NormalizedNote>,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamChatMessageEvent {
pub account_id: String,
pub subscription_id: String,
pub message: ChatMessage,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamChatMessageDeletedEvent {
pub account_id: String,
Expand All @@ -142,7 +157,8 @@ struct ChatReactionWsBody {
user: Option<ChatReactionUser>,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamChatMessageReactedEvent {
pub account_id: String,
Expand All @@ -152,7 +168,8 @@ pub struct StreamChatMessageReactedEvent {
pub user: Option<ChatReactionUser>,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamChatMessageUnreactedEvent {
pub account_id: String,
Expand All @@ -162,7 +179,8 @@ pub struct StreamChatMessageUnreactedEvent {
pub user: Option<ChatReactionUser>,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamMainEvent {
pub account_id: String,
Expand All @@ -171,7 +189,8 @@ pub struct StreamMainEvent {
pub body: Value,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamNoteUpdatedEvent {
pub account_id: String,
Expand All @@ -182,7 +201,8 @@ pub struct StreamNoteUpdatedEvent {
pub update: NoteUpdateBody,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamNoteCaptureEvent {
pub account_id: String,
Expand All @@ -191,11 +211,12 @@ pub struct StreamNoteCaptureEvent {
pub update: NoteUpdateBody,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "specta", derive(specta::Type))]
#[serde(rename_all = "camelCase")]
pub struct StreamStatusEvent {
pub account_id: String,
pub state: String,
pub state: StreamConnectionState,
}

// --- Internal commands sent to the WebSocket task ---
Expand Down Expand Up @@ -300,16 +321,16 @@ impl StreamingManager {
// 取り逃した状態遷移をここで補正できる (楽観的に connected と
// 見なす JS 側ロジックを置かないための供給側の責務)。
let state = if handle.connected.load(std::sync::atomic::Ordering::Relaxed) {
"connected"
StreamConnectionState::Connected
} else {
"reconnecting"
StreamConnectionState::Reconnecting
};
emit_or_log!(
self.emitter,
"stream-status",
StreamStatusEvent {
account_id: account_id.to_string(),
state: state.to_string(),
state,
}
);
return Ok(());
Expand Down Expand Up @@ -391,7 +412,11 @@ impl StreamingManager {
"stream-status",
StreamStatusEvent {
account_id: account_id.to_string(),
state: if connected { "connected" } else { "reconnecting" }.to_string(),
state: if connected {
StreamConnectionState::Connected
} else {
StreamConnectionState::Reconnecting
},
}
);

Expand Down Expand Up @@ -434,7 +459,7 @@ impl StreamingManager {
"stream-status",
StreamStatusEvent {
account_id: account_id.to_string(),
state: "disconnected".to_string(),
state: StreamConnectionState::Disconnected,
}
);
}
Expand Down Expand Up @@ -480,7 +505,7 @@ impl StreamingManager {
"stream-status",
StreamStatusEvent {
account_id: account_id.to_string(),
state: "connected".to_string(),
state: StreamConnectionState::Connected,
}
);
}
Expand Down Expand Up @@ -1000,7 +1025,7 @@ async fn connection_task(
"stream-status",
StreamStatusEvent {
account_id: account_id.clone(),
state: "reconnecting".to_string(),
state: StreamConnectionState::Reconnecting,
}
);

Expand Down Expand Up @@ -1047,7 +1072,7 @@ async fn connection_task(
"stream-status",
StreamStatusEvent {
account_id: account_id.clone(),
state: "connected".to_string(),
state: StreamConnectionState::Connected,
}
);

Expand Down Expand Up @@ -1809,7 +1834,7 @@ async fn polling_loop(
"stream-status",
StreamStatusEvent {
account_id: account_id.clone(),
state: "reconnecting".to_string(),
state: StreamConnectionState::Reconnecting,
}
);

Expand Down
Loading