From 653e2de752a97e377fc9963ba60d9408e7089528 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 8 Oct 2024 22:10:04 -0400 Subject: Flatten nested `channel` and `message` structs in events and API responses. This structure didn't accomplish anything and made certain refactorings harder. --- src/message/event.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/message/event.rs') diff --git a/src/message/event.rs b/src/message/event.rs index 66db9b0..712ecc1 100644 --- a/src/message/event.rs +++ b/src/message/event.rs @@ -55,7 +55,7 @@ pub struct Deleted { #[serde(flatten)] pub instant: Instant, pub channel: Channel, - pub message: Id, + pub id: Id, } impl Sequenced for Deleted { -- cgit v1.2.3 From 9e171096a72d3e63626df7b09970476aba28eb06 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 8 Oct 2024 22:43:22 -0400 Subject: Use a two-tier hierarchy for events. This will make it much easier to slot in new event types (login events!). --- docs/api.md | 10 +++++-- hi-ui/src/apiServer.js | 40 +++++++++++++++++--------- hi-ui/src/store/messages.js | 4 +-- src/channel/event.rs | 29 ++++++++++--------- src/channel/history.rs | 16 +++++------ src/channel/routes/test/on_create.rs | 6 ++-- src/channel/routes/test/on_send.rs | 10 +++---- src/channel/snapshot.rs | 8 +++--- src/event/mod.rs | 54 +++++++----------------------------- src/event/sequence.rs | 4 +++ src/message/event.rs | 22 ++++----------- src/message/history.rs | 14 ++++------ src/message/snapshot.rs | 10 +++---- src/test/fixtures/event.rs | 8 +++--- src/test/fixtures/filter.rs | 6 ++-- 15 files changed, 106 insertions(+), 135 deletions(-) (limited to 'src/message/event.rs') diff --git a/docs/api.md b/docs/api.md index 13e71c7..73bfb38 100644 --- a/docs/api.md +++ b/docs/api.md @@ -200,7 +200,8 @@ The returned event stream is a sequence of events: ```json id: 1233 data: { -data: "type": "created", +data: "type": "channel", +data: "event": "created", data: "at": "2024-09-27T23:18:10.208147Z", data: "id": "C9876cyyz", data: "name": "example channel 2" @@ -209,6 +210,7 @@ data: } id: 1234 data: { data: "type": "message", +data: "event": "sent", data: "at": "2024-09-27T23:19:10.208147Z", data: "channel": { data: "id": "C9876cyyz", @@ -224,19 +226,21 @@ data: } id: 1235 data: { +data: "type": "message", +data: "event": "deleted", data: "at": "2024-09-28T02:44:27.077355Z", data: "channel": { data: "id": "C9876cyyz", data: "name": "example channel 2" data: }, -data: "type": "message_deleted", data: "id": "M1312acab" data: } id: 1236 data: { +data: "type": "channel", +data: "event": "deleted", data: "at": "2024-09-28T03:40:25.384318Z", -data: "type": "deleted", data: "id": "C9876cyyz" data: } diff --git a/hi-ui/src/apiServer.js b/hi-ui/src/apiServer.js index ec94e82..648edf5 100644 --- a/hi-ui/src/apiServer.js +++ b/hi-ui/src/apiServer.js @@ -55,22 +55,36 @@ export function subscribeToEvents(resume_point) { const data = JSON.parse(evt.data); switch (data.type) { - case 'created': - channelsList.update((value) => value.addChannel(data.id, data.name)) + case 'channel': + onChannelEvent(data); break; case 'message': - messages.update((value) => value.addMessage(data)); - break; - case 'message_deleted': - messages.update((value) => value.deleteMessage(data.channel.id, data.id)); - break; - case 'deleted': - activeChannel.update((value) => value.deleteChannel(data.id)); - channelsList.update((value) => value.deleteChannel(data.id)); - messages.update((value) => value.deleteChannel(data.id)); - break; - default: + onMessageEvent(data); break; } } } + +function onChannelEvent(data) { + switch (data.event) { + case 'created': + channelsList.update((value) => value.addChannel(data.id, data.name)) + break; + case 'deleted': + activeChannel.update((value) => value.deleteChannel(data.id)); + channelsList.update((value) => value.deleteChannel(data.id)); + messages.update((value) => value.deleteChannel(data.id)); + break; + } +} + +function onMessageEvent(data) { + switch (data.event) { + case 'sent': + messages.update((value) => value.addMessage(data)); + break; + case 'deleted': + messages.update((value) => value.deleteMessage(data.channel.id, data.id)); + break; + } +} diff --git a/hi-ui/src/store/messages.js b/hi-ui/src/store/messages.js index 560b9e1..cefd725 100644 --- a/hi-ui/src/store/messages.js +++ b/hi-ui/src/store/messages.js @@ -24,8 +24,8 @@ export class Messages { deleteMessage(channel, message) { - let messages = this.messages(channel).filter((msg) => msg.message.id != message); - this.channels[channel] = messages; + this.updateChannel(channel, (messages) => messages.filter((msg) => msg.id != message)); + return this; } deleteChannel(id) { diff --git a/src/channel/event.rs b/src/channel/event.rs index 9f2e263..f3dca3e 100644 --- a/src/channel/event.rs +++ b/src/channel/event.rs @@ -5,33 +5,30 @@ use crate::{ }; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -pub struct Event { - #[serde(flatten)] - pub instant: Instant, - #[serde(flatten)] - pub kind: Kind, +#[serde(tag = "event", rename_all = "snake_case")] +pub enum Event { + Created(Created), + Deleted(Deleted), } impl Sequenced for Event { fn instant(&self) -> Instant { - self.instant + match self { + Self::Created(event) => event.instant, + Self::Deleted(event) => event.instant, + } } } -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum Kind { - Created(Created), - Deleted(Deleted), -} - #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct Created { + #[serde(flatten)] + pub instant: Instant, #[serde(flatten)] pub channel: Channel, } -impl From for Kind { +impl From for Event { fn from(event: Created) -> Self { Self::Created(event) } @@ -39,10 +36,12 @@ impl From for Kind { #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct Deleted { + #[serde(flatten)] + pub instant: Instant, pub id: channel::Id, } -impl From for Kind { +impl From for Event { fn from(event: Deleted) -> Self { Self::Deleted(event) } diff --git a/src/channel/history.rs b/src/channel/history.rs index 0499927..78b3437 100644 --- a/src/channel/history.rs +++ b/src/channel/history.rs @@ -40,22 +40,20 @@ impl History { } fn created(&self) -> Event { - Event { + Created { instant: self.created, - kind: Created { - channel: self.channel.clone(), - } - .into(), + channel: self.channel.clone(), } + .into() } fn deleted(&self) -> Option { - self.deleted.map(|instant| Event { - instant, - kind: Deleted { + self.deleted.map(|instant| { + Deleted { + instant, id: self.channel.id.clone(), } - .into(), + .into() }) } } diff --git a/src/channel/routes/test/on_create.rs b/src/channel/routes/test/on_create.rs index ed49017..8c3c62b 100644 --- a/src/channel/routes/test/on_create.rs +++ b/src/channel/routes/test/on_create.rs @@ -2,7 +2,7 @@ use axum::extract::{Json, State}; use futures::stream::StreamExt as _; use crate::{ - channel::{app, routes}, + channel::{self, app, routes}, event, test::fixtures::{self, future::Immediately as _}, }; @@ -53,8 +53,8 @@ async fn new_channel() { .expect("creation event published"); assert!(matches!( - event.kind, - event::Kind::ChannelCreated(event) + event, + event::Event::Channel(channel::Event::Created(event)) if event.channel == response_channel )); } diff --git a/src/channel/routes/test/on_send.rs b/src/channel/routes/test/on_send.rs index 3297093..d2acc48 100644 --- a/src/channel/routes/test/on_send.rs +++ b/src/channel/routes/test/on_send.rs @@ -4,8 +4,8 @@ use futures::stream::StreamExt; use crate::{ channel, channel::routes, - event, - message::app::SendError, + event::{self, Sequenced}, + message::{self, app::SendError}, test::fixtures::{self, future::Immediately as _}, }; @@ -53,10 +53,10 @@ async fn messages_in_order() { let events = events.collect::>().immediately().await; for ((sent_at, message), event) in requests.into_iter().zip(events) { - assert_eq!(*sent_at, event.instant.at); + assert_eq!(*sent_at, event.at()); assert!(matches!( - event.kind, - event::Kind::MessageSent(event) + event, + event::Event::Message(message::Event::Sent(event)) if event.message.sender == sender && event.message.body == message )); diff --git a/src/channel/snapshot.rs b/src/channel/snapshot.rs index afef2fb..d4d1d27 100644 --- a/src/channel/snapshot.rs +++ b/src/channel/snapshot.rs @@ -1,5 +1,5 @@ use super::{ - event::{Created, Event, Kind}, + event::{Created, Event}, Id, }; @@ -11,9 +11,9 @@ pub struct Channel { impl Channel { fn apply(state: Option, event: Event) -> Option { - match (state, event.kind) { - (None, Kind::Created(event)) => Some(event.into()), - (Some(channel), Kind::Deleted(event)) if channel.id == event.id => None, + match (state, event) { + (None, Event::Created(event)) => Some(event.into()), + (Some(channel), Event::Deleted(event)) if channel.id == event.id => None, (state, event) => panic!("invalid channel event {event:#?} for state {state:#?}"), } } diff --git a/src/event/mod.rs b/src/event/mod.rs index e748d66..698e55a 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -15,63 +15,29 @@ pub use self::{ pub type ResumePoint = Option; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -pub struct Event { - #[serde(flatten)] - pub instant: Instant, - #[serde(flatten)] - pub kind: Kind, +#[serde(tag = "type", rename_all = "snake_case")] +pub enum Event { + Channel(channel::Event), + Message(message::Event), } impl Sequenced for Event { fn instant(&self) -> Instant { - self.instant + match self { + Self::Channel(event) => event.instant(), + Self::Message(event) => event.instant(), + } } } impl From for Event { fn from(event: channel::Event) -> Self { - Self { - instant: event.instant, - kind: event.kind.into(), - } + Self::Channel(event) } } impl From for Event { fn from(event: message::Event) -> Self { - Self { - instant: event.instant(), - kind: event.kind.into(), - } - } -} - -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum Kind { - #[serde(rename = "created")] - ChannelCreated(channel::event::Created), - #[serde(rename = "message")] - MessageSent(message::event::Sent), - MessageDeleted(message::event::Deleted), - #[serde(rename = "deleted")] - ChannelDeleted(channel::event::Deleted), -} - -impl From for Kind { - fn from(kind: channel::event::Kind) -> Self { - match kind { - channel::event::Kind::Created(created) => Self::ChannelCreated(created), - channel::event::Kind::Deleted(deleted) => Self::ChannelDeleted(deleted), - } - } -} - -impl From for Kind { - fn from(kind: message::event::Kind) -> Self { - match kind { - message::event::Kind::Sent(created) => Self::MessageSent(created), - message::event::Kind::Deleted(deleted) => Self::MessageDeleted(deleted), - } + Self::Message(event) } } diff --git a/src/event/sequence.rs b/src/event/sequence.rs index ceb5bcb..bf6d5b8 100644 --- a/src/event/sequence.rs +++ b/src/event/sequence.rs @@ -72,6 +72,10 @@ impl Sequence { pub trait Sequenced { fn instant(&self) -> Instant; + fn at(&self) -> DateTime { + self.instant().at + } + fn sequence(&self) -> Sequence { self.instant().into() } diff --git a/src/message/event.rs b/src/message/event.rs index 712ecc1..9f49a32 100644 --- a/src/message/event.rs +++ b/src/message/event.rs @@ -5,25 +5,13 @@ use crate::{ }; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -pub struct Event { - #[serde(flatten)] - pub kind: Kind, -} - -impl Sequenced for Event { - fn instant(&self) -> Instant { - self.kind.instant() - } -} - -#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum Kind { +#[serde(tag = "event", rename_all = "snake_case")] +pub enum Event { Sent(Sent), Deleted(Deleted), } -impl Sequenced for Kind { +impl Sequenced for Event { fn instant(&self) -> Instant { match self { Self::Sent(sent) => sent.instant(), @@ -44,7 +32,7 @@ impl Sequenced for Sent { } } -impl From for Kind { +impl From for Event { fn from(event: Sent) -> Self { Self::Sent(event) } @@ -64,7 +52,7 @@ impl Sequenced for Deleted { } } -impl From for Kind { +impl From for Event { fn from(event: Deleted) -> Self { Self::Deleted(event) } diff --git a/src/message/history.rs b/src/message/history.rs index 3c3f77a..b5886af 100644 --- a/src/message/history.rs +++ b/src/message/history.rs @@ -35,22 +35,20 @@ impl History { // Events interface impl History { fn sent(&self) -> Event { - Event { - kind: Sent { - message: self.message.clone(), - } - .into(), + Sent { + message: self.message.clone(), } + .into() } fn deleted(&self) -> Option { - self.deleted.map(|instant| Event { - kind: Deleted { + self.deleted.map(|instant| { + Deleted { instant, channel: self.message.channel.clone(), id: self.message.id.clone(), } - .into(), + .into() }) } diff --git a/src/message/snapshot.rs b/src/message/snapshot.rs index a06fbc4..a8cf734 100644 --- a/src/message/snapshot.rs +++ b/src/message/snapshot.rs @@ -1,12 +1,12 @@ use super::{ - event::{Event, Kind, Sent}, + event::{Event, Sent}, Id, }; use crate::{channel::Channel, event::Instant, login::Login}; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct Message { - #[serde(skip)] + #[serde(flatten)] pub sent: Instant, pub channel: Channel, pub sender: Login, @@ -16,9 +16,9 @@ pub struct Message { impl Message { fn apply(state: Option, event: Event) -> Option { - match (state, event.kind) { - (None, Kind::Sent(event)) => Some(event.into()), - (Some(message), Kind::Deleted(event)) if message.id == event.id => None, + match (state, event) { + (None, Event::Sent(event)) => Some(event.into()), + (Some(message), Event::Deleted(event)) if message.id == event.id => None, (state, event) => panic!("invalid message event {event:#?} for state {state:#?}"), } } diff --git a/src/test/fixtures/event.rs b/src/test/fixtures/event.rs index 09f0490..7fe2bf3 100644 --- a/src/test/fixtures/event.rs +++ b/src/test/fixtures/event.rs @@ -1,11 +1,11 @@ use crate::{ - event::{Event, Kind}, - message::Message, + event::Event, + message::{Event::Sent, Message}, }; pub fn message_sent(event: &Event, message: &Message) -> bool { matches!( - &event.kind, - Kind::MessageSent(event) if message == &event.into() + &event, + Event::Message(Sent(event)) if message == &event.into() ) } diff --git a/src/test/fixtures/filter.rs b/src/test/fixtures/filter.rs index 6e62aea..84d27b0 100644 --- a/src/test/fixtures/filter.rs +++ b/src/test/fixtures/filter.rs @@ -1,11 +1,11 @@ use futures::future; -use crate::event::{Event, Kind}; +use crate::{channel::Event::Created, event::Event, message::Event::Sent}; pub fn messages() -> impl FnMut(&Event) -> future::Ready { - |event| future::ready(matches!(event.kind, Kind::MessageSent(_))) + |event| future::ready(matches!(event, Event::Message(Sent(_)))) } pub fn created() -> impl FnMut(&Event) -> future::Ready { - |event| future::ready(matches!(event.kind, Kind::ChannelCreated(_))) + |event| future::ready(matches!(event, Event::Channel(Created(_)))) } -- cgit v1.2.3 From da1810afc5a627a518131cfb0af0996c5ec60bcf Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Tue, 8 Oct 2024 22:57:39 -0400 Subject: Simplify channel IDs in events. Remove redundant ones. --- ...0061d4bf5755cda35dba473eae37f467cfabb0102e.json | 56 +++++++++++++++++++ ...0bd021892002b7ba7d9f4cac5deea298b6223918aa.json | 56 +++++++++++++++++++ ...4eedb8229360ba78f2607d25e7e2ee5db5c759a5a3.json | 62 ---------------------- ...9cedc6bee1750d28a6176980ed7040b8a3301fc7e5.json | 62 ---------------------- ...4a2137be57b3a45fe38a675262ceaaebb3d346a9ca.json | 62 ---------------------- ...47a7317dda3e429faac15e02c900f62f83c25070a7.json | 56 +++++++++++++++++++ docs/api.md | 9 +--- hi-ui/src/apiServer.js | 4 +- hi-ui/src/store/messages.js | 15 +++--- src/message/event.rs | 6 +-- src/message/history.rs | 1 - src/message/repo.rs | 36 ++++--------- src/message/snapshot.rs | 4 +- 13 files changed, 189 insertions(+), 240 deletions(-) create mode 100644 .sqlx/query-14ca0364c6f0ab084b22af0061d4bf5755cda35dba473eae37f467cfabb0102e.json create mode 100644 .sqlx/query-315a4a16ebc0a99ab745a40bd021892002b7ba7d9f4cac5deea298b6223918aa.json delete mode 100644 .sqlx/query-5c53579fa431b6e184faf94eedb8229360ba78f2607d25e7e2ee5db5c759a5a3.json delete mode 100644 .sqlx/query-6fc4be85527af518da17c49cedc6bee1750d28a6176980ed7040b8a3301fc7e5.json delete mode 100644 .sqlx/query-9606853f2ea9f776f7e4384a2137be57b3a45fe38a675262ceaaebb3d346a9ca.json create mode 100644 .sqlx/query-eb9d7146e615044568f9bb47a7317dda3e429faac15e02c900f62f83c25070a7.json (limited to 'src/message/event.rs') diff --git a/.sqlx/query-14ca0364c6f0ab084b22af0061d4bf5755cda35dba473eae37f467cfabb0102e.json b/.sqlx/query-14ca0364c6f0ab084b22af0061d4bf5755cda35dba473eae37f467cfabb0102e.json new file mode 100644 index 0000000..15ceb24 --- /dev/null +++ b/.sqlx/query-14ca0364c6f0ab084b22af0061d4bf5755cda35dba473eae37f467cfabb0102e.json @@ -0,0 +1,56 @@ +{ + "db_name": "SQLite", + "query": "\n select\n message.channel as \"channel: channel::Id\",\n sender.id as \"sender_id: login::Id\",\n sender.name as \"sender_name\",\n message.id as \"id: Id\",\n message.body,\n sent_at as \"sent_at: DateTime\",\n sent_sequence as \"sent_sequence: Sequence\"\n from message\n join login as sender on message.sender = sender.id\n where coalesce(message.sent_sequence > $1, true)\n ", + "describe": { + "columns": [ + { + "name": "channel: channel::Id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "sender_id: login::Id", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "sender_name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "id: Id", + "ordinal": 3, + "type_info": "Text" + }, + { + "name": "body", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "sent_at: DateTime", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "sent_sequence: Sequence", + "ordinal": 6, + "type_info": "Integer" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + false + ] + }, + "hash": "14ca0364c6f0ab084b22af0061d4bf5755cda35dba473eae37f467cfabb0102e" +} diff --git a/.sqlx/query-315a4a16ebc0a99ab745a40bd021892002b7ba7d9f4cac5deea298b6223918aa.json b/.sqlx/query-315a4a16ebc0a99ab745a40bd021892002b7ba7d9f4cac5deea298b6223918aa.json new file mode 100644 index 0000000..7aeac69 --- /dev/null +++ b/.sqlx/query-315a4a16ebc0a99ab745a40bd021892002b7ba7d9f4cac5deea298b6223918aa.json @@ -0,0 +1,56 @@ +{ + "db_name": "SQLite", + "query": "\n select\n message.channel as \"channel: channel::Id\",\n sender.id as \"sender_id: login::Id\",\n sender.name as \"sender_name\",\n message.id as \"id: Id\",\n message.body,\n sent_at as \"sent_at: DateTime\",\n sent_sequence as \"sent_sequence: Sequence\"\n from message\n join login as sender on message.sender = sender.id\n where message.id = $1\n ", + "describe": { + "columns": [ + { + "name": "channel: channel::Id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "sender_id: login::Id", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "sender_name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "id: Id", + "ordinal": 3, + "type_info": "Text" + }, + { + "name": "body", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "sent_at: DateTime", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "sent_sequence: Sequence", + "ordinal": 6, + "type_info": "Integer" + } + ], + "parameters": { + "Right": 1 + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + false + ] + }, + "hash": "315a4a16ebc0a99ab745a40bd021892002b7ba7d9f4cac5deea298b6223918aa" +} diff --git a/.sqlx/query-5c53579fa431b6e184faf94eedb8229360ba78f2607d25e7e2ee5db5c759a5a3.json b/.sqlx/query-5c53579fa431b6e184faf94eedb8229360ba78f2607d25e7e2ee5db5c759a5a3.json deleted file mode 100644 index 4ca6786..0000000 --- a/.sqlx/query-5c53579fa431b6e184faf94eedb8229360ba78f2607d25e7e2ee5db5c759a5a3.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n select\n channel.id as \"channel_id: channel::Id\",\n channel.name as \"channel_name\",\n sender.id as \"sender_id: login::Id\",\n sender.name as \"sender_name\",\n message.id as \"id: Id\",\n message.body,\n sent_at as \"sent_at: DateTime\",\n sent_sequence as \"sent_sequence: Sequence\"\n from message\n join channel on message.channel = channel.id\n join login as sender on message.sender = sender.id\n where coalesce(message.sent_sequence > $1, true)\n ", - "describe": { - "columns": [ - { - "name": "channel_id: channel::Id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "channel_name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "sender_id: login::Id", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "sender_name", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "id: Id", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "body", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "sent_at: DateTime", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "sent_sequence: Sequence", - "ordinal": 7, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - "hash": "5c53579fa431b6e184faf94eedb8229360ba78f2607d25e7e2ee5db5c759a5a3" -} diff --git a/.sqlx/query-6fc4be85527af518da17c49cedc6bee1750d28a6176980ed7040b8a3301fc7e5.json b/.sqlx/query-6fc4be85527af518da17c49cedc6bee1750d28a6176980ed7040b8a3301fc7e5.json deleted file mode 100644 index 257e1f6..0000000 --- a/.sqlx/query-6fc4be85527af518da17c49cedc6bee1750d28a6176980ed7040b8a3301fc7e5.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n select\n channel.id as \"channel_id: channel::Id\",\n channel.name as \"channel_name\",\n sender.id as \"sender_id: login::Id\",\n sender.name as \"sender_name\",\n message.id as \"id: Id\",\n message.body,\n sent_at as \"sent_at: DateTime\",\n sent_sequence as \"sent_sequence: Sequence\"\n from message\n join channel on message.channel = channel.id\n join login as sender on message.sender = sender.id\n where message.id = $1\n ", - "describe": { - "columns": [ - { - "name": "channel_id: channel::Id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "channel_name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "sender_id: login::Id", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "sender_name", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "id: Id", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "body", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "sent_at: DateTime", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "sent_sequence: Sequence", - "ordinal": 7, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - "hash": "6fc4be85527af518da17c49cedc6bee1750d28a6176980ed7040b8a3301fc7e5" -} diff --git a/.sqlx/query-9606853f2ea9f776f7e4384a2137be57b3a45fe38a675262ceaaebb3d346a9ca.json b/.sqlx/query-9606853f2ea9f776f7e4384a2137be57b3a45fe38a675262ceaaebb3d346a9ca.json deleted file mode 100644 index 82246ac..0000000 --- a/.sqlx/query-9606853f2ea9f776f7e4384a2137be57b3a45fe38a675262ceaaebb3d346a9ca.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n select\n channel.id as \"channel_id: channel::Id\",\n channel.name as \"channel_name\",\n sender.id as \"sender_id: login::Id\",\n sender.name as \"sender_name\",\n message.id as \"id: Id\",\n message.body,\n sent_at as \"sent_at: DateTime\",\n sent_sequence as \"sent_sequence: Sequence\"\n from message\n join channel on message.channel = channel.id\n join login as sender on message.sender = sender.id\n where channel.id = $1\n and coalesce(message.sent_sequence <= $2, true)\n order by message.sent_sequence\n ", - "describe": { - "columns": [ - { - "name": "channel_id: channel::Id", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "channel_name", - "ordinal": 1, - "type_info": "Text" - }, - { - "name": "sender_id: login::Id", - "ordinal": 2, - "type_info": "Text" - }, - { - "name": "sender_name", - "ordinal": 3, - "type_info": "Text" - }, - { - "name": "id: Id", - "ordinal": 4, - "type_info": "Text" - }, - { - "name": "body", - "ordinal": 5, - "type_info": "Text" - }, - { - "name": "sent_at: DateTime", - "ordinal": 6, - "type_info": "Text" - }, - { - "name": "sent_sequence: Sequence", - "ordinal": 7, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false, - false, - false, - false, - false, - false, - false, - false - ] - }, - "hash": "9606853f2ea9f776f7e4384a2137be57b3a45fe38a675262ceaaebb3d346a9ca" -} diff --git a/.sqlx/query-eb9d7146e615044568f9bb47a7317dda3e429faac15e02c900f62f83c25070a7.json b/.sqlx/query-eb9d7146e615044568f9bb47a7317dda3e429faac15e02c900f62f83c25070a7.json new file mode 100644 index 0000000..1fe8a3e --- /dev/null +++ b/.sqlx/query-eb9d7146e615044568f9bb47a7317dda3e429faac15e02c900f62f83c25070a7.json @@ -0,0 +1,56 @@ +{ + "db_name": "SQLite", + "query": "\n select\n message.channel as \"channel: channel::Id\",\n sender.id as \"sender_id: login::Id\",\n sender.name as \"sender_name\",\n message.id as \"id: Id\",\n message.body,\n sent_at as \"sent_at: DateTime\",\n sent_sequence as \"sent_sequence: Sequence\"\n from message\n join login as sender on message.sender = sender.id\n where message.channel = $1\n and coalesce(message.sent_sequence <= $2, true)\n order by message.sent_sequence\n ", + "describe": { + "columns": [ + { + "name": "channel: channel::Id", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "sender_id: login::Id", + "ordinal": 1, + "type_info": "Text" + }, + { + "name": "sender_name", + "ordinal": 2, + "type_info": "Text" + }, + { + "name": "id: Id", + "ordinal": 3, + "type_info": "Text" + }, + { + "name": "body", + "ordinal": 4, + "type_info": "Text" + }, + { + "name": "sent_at: DateTime", + "ordinal": 5, + "type_info": "Text" + }, + { + "name": "sent_sequence: Sequence", + "ordinal": 6, + "type_info": "Integer" + } + ], + "parameters": { + "Right": 2 + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + false + ] + }, + "hash": "eb9d7146e615044568f9bb47a7317dda3e429faac15e02c900f62f83c25070a7" +} diff --git a/docs/api.md b/docs/api.md index 73bfb38..56d361d 100644 --- a/docs/api.md +++ b/docs/api.md @@ -212,10 +212,7 @@ data: { data: "type": "message", data: "event": "sent", data: "at": "2024-09-27T23:19:10.208147Z", -data: "channel": { -data: "id": "C9876cyyz", -data: "name": "example channel 2" -data: }, +data: "channel": "C9876cyyz", data: "sender": { data: "id": "L1234abcd", data: "name": "example username" @@ -229,10 +226,6 @@ data: { data: "type": "message", data: "event": "deleted", data: "at": "2024-09-28T02:44:27.077355Z", -data: "channel": { -data: "id": "C9876cyyz", -data: "name": "example channel 2" -data: }, data: "id": "M1312acab" data: } diff --git a/hi-ui/src/apiServer.js b/hi-ui/src/apiServer.js index 648edf5..e87e2d6 100644 --- a/hi-ui/src/apiServer.js +++ b/hi-ui/src/apiServer.js @@ -81,10 +81,10 @@ function onChannelEvent(data) { function onMessageEvent(data) { switch (data.event) { case 'sent': - messages.update((value) => value.addMessage(data)); + messages.update((value) => value.addMessage(data.channel, data.at, data.sender, data.body)); break; case 'deleted': - messages.update((value) => value.deleteMessage(data.channel.id, data.id)); + messages.update((value) => value.deleteMessage(data.id)); break; } } diff --git a/hi-ui/src/store/messages.js b/hi-ui/src/store/messages.js index cefd725..f9e0856 100644 --- a/hi-ui/src/store/messages.js +++ b/hi-ui/src/store/messages.js @@ -7,13 +7,8 @@ export class Messages { return this.channels[channel] || []; } - addMessage(message) { - let { - channel, - ...payload - } = message; - let channel_id = channel.id; - this.updateChannel(channel_id, (messages) => [...messages, payload]); + addMessage(channel, at, sender, body) { + this.updateChannel(channel, (messages) => [...messages, { at, sender, body }]); return this; } @@ -23,8 +18,10 @@ export class Messages { } - deleteMessage(channel, message) { - this.updateChannel(channel, (messages) => messages.filter((msg) => msg.id != message)); + deleteMessage(message) { + for (let channel in this.channels) { + this.updateChannel(channel, (messages) => messages.filter((msg) => msg.id != message)); + } return this; } diff --git a/src/message/event.rs b/src/message/event.rs index 9f49a32..1cd5847 100644 --- a/src/message/event.rs +++ b/src/message/event.rs @@ -1,8 +1,5 @@ use super::{snapshot::Message, Id}; -use crate::{ - channel::Channel, - event::{Instant, Sequenced}, -}; +use crate::event::{Instant, Sequenced}; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] #[serde(tag = "event", rename_all = "snake_case")] @@ -42,7 +39,6 @@ impl From for Event { pub struct Deleted { #[serde(flatten)] pub instant: Instant, - pub channel: Channel, pub id: Id, } diff --git a/src/message/history.rs b/src/message/history.rs index b5886af..09e69b7 100644 --- a/src/message/history.rs +++ b/src/message/history.rs @@ -45,7 +45,6 @@ impl History { self.deleted.map(|instant| { Deleted { instant, - channel: self.message.channel.clone(), id: self.message.id.clone(), } .into() diff --git a/src/message/repo.rs b/src/message/repo.rs index 5b199a7..e098fb2 100644 --- a/src/message/repo.rs +++ b/src/message/repo.rs @@ -2,7 +2,7 @@ use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction}; use super::{snapshot::Message, History, Id}; use crate::{ - channel::{self, Channel}, + channel, clock::DateTime, event::{Instant, ResumePoint, Sequence}, login::{self, Login}, @@ -50,10 +50,7 @@ impl<'c> Messages<'c> { .map(|row| History { message: Message { sent: *sent, - // Use "as created" here as we don't care about providing a perfectly up-to-date - // representation of the channel. The `name` is informational (and the ID, which is - // normative, is fixed over time). - channel: channel.as_created(), + channel: channel.id().clone(), sender: sender.clone(), id: row.id, body: row.body, @@ -75,8 +72,7 @@ impl<'c> Messages<'c> { let messages = sqlx::query!( r#" select - channel.id as "channel_id: channel::Id", - channel.name as "channel_name", + message.channel as "channel: channel::Id", sender.id as "sender_id: login::Id", sender.name as "sender_name", message.id as "id: Id", @@ -84,9 +80,8 @@ impl<'c> Messages<'c> { sent_at as "sent_at: DateTime", sent_sequence as "sent_sequence: Sequence" from message - join channel on message.channel = channel.id join login as sender on message.sender = sender.id - where channel.id = $1 + where message.channel = $1 and coalesce(message.sent_sequence <= $2, true) order by message.sent_sequence "#, @@ -99,10 +94,7 @@ impl<'c> Messages<'c> { at: row.sent_at, sequence: row.sent_sequence, }, - channel: Channel { - id: row.channel_id, - name: row.channel_name, - }, + channel: row.channel, sender: Login { id: row.sender_id, name: row.sender_name, @@ -122,8 +114,7 @@ impl<'c> Messages<'c> { let message = sqlx::query!( r#" select - channel.id as "channel_id: channel::Id", - channel.name as "channel_name", + message.channel as "channel: channel::Id", sender.id as "sender_id: login::Id", sender.name as "sender_name", message.id as "id: Id", @@ -131,7 +122,6 @@ impl<'c> Messages<'c> { sent_at as "sent_at: DateTime", sent_sequence as "sent_sequence: Sequence" from message - join channel on message.channel = channel.id join login as sender on message.sender = sender.id where message.id = $1 "#, @@ -143,10 +133,7 @@ impl<'c> Messages<'c> { at: row.sent_at, sequence: row.sent_sequence, }, - channel: Channel { - id: row.channel_id, - name: row.channel_name, - }, + channel: row.channel, sender: Login { id: row.sender_id, name: row.sender_name, @@ -207,8 +194,7 @@ impl<'c> Messages<'c> { let messages = sqlx::query!( r#" select - channel.id as "channel_id: channel::Id", - channel.name as "channel_name", + message.channel as "channel: channel::Id", sender.id as "sender_id: login::Id", sender.name as "sender_name", message.id as "id: Id", @@ -216,7 +202,6 @@ impl<'c> Messages<'c> { sent_at as "sent_at: DateTime", sent_sequence as "sent_sequence: Sequence" from message - join channel on message.channel = channel.id join login as sender on message.sender = sender.id where coalesce(message.sent_sequence > $1, true) "#, @@ -228,10 +213,7 @@ impl<'c> Messages<'c> { at: row.sent_at, sequence: row.sent_sequence, }, - channel: Channel { - id: row.channel_id, - name: row.channel_name, - }, + channel: row.channel, sender: Login { id: row.sender_id, name: row.sender_name, diff --git a/src/message/snapshot.rs b/src/message/snapshot.rs index a8cf734..8c1e62a 100644 --- a/src/message/snapshot.rs +++ b/src/message/snapshot.rs @@ -2,13 +2,13 @@ use super::{ event::{Event, Sent}, Id, }; -use crate::{channel::Channel, event::Instant, login::Login}; +use crate::{channel, event::Instant, login::Login}; #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct Message { #[serde(flatten)] pub sent: Instant, - pub channel: Channel, + pub channel: channel::Id, pub sender: Login, pub id: Id, pub body: String, -- cgit v1.2.3