Live updates, votes, likes and the chat travel over one WebSocket between
WSProvider in the client and routes/ws.ts in the server. This module
types its messages, JSON objects told apart by type.
The server's messages go out from services/ws-service.ts, and WSProvider
handles them. Their Dates arrive as strings, so the client reads them as
Wire<ServerToClientMessage> and deserializes what it keeps.
Sent by the category service to every socket after a category is created,
edited or deleted. CategoriesProvider fetches the categories again.
Sent by WSProvider when the user deletes a chat message, as
ChatEditMessage. The server broadcasts
ChatMessageDeletedMessage.
Sent by WSProvider when the user edits a chat message, their own or, with
chat:moderate, anyone's. The server broadcasts
ChatMessageUpdatedMessage, or answers a chat ErrorMessage.
Sent by WSProvider when the chatbox opens or closes, when the tab is
hidden or shown, and after each welcome. The server notifies no one of a
chat mention while one of their sockets says open.
-
open: boolean
True only while the chatbox is open in a visible tab.
- type: "chat_focus"
Sent by the server to every signed-in socket when a chat message is deleted. The client also keeps the id, to show the replies to it as replies to a deleted message.
Sent by the server to every signed-in socket, the sender's included, when a
chat message is posted. WSProvider adds it to the live chat, counts it
unread unless the user is reading the chat, and may chime.
- message: ChatMessage
-
nonce: string
The sender's ChatSendMessage nonce, by which its client swaps the pending copy for this one.
- type: "chat_message"
Sent by the server to every signed-in socket when a chat message is edited.
Sent by WSProvider, at most once a second, as the user reads the chat. The
server moves their read marker to at, a message's ISO createdAt, and
answers ChatReadUpdateMessage. It drops the message silently when it
is malformed or over its rate limit.
Sent by the server to every socket of a user after their ChatReadMessage, so that all their tabs and devices update the chat's badge.
- readAt: string
- type: "chat_read_update"
-
unread: number
Counts only the messages of other users after
readAt.
Sent by WSProvider when the user posts in the chatbox, which shows the
message as pending meanwhile. The server broadcasts it as
ChatMessageMessage, or answers a chat ErrorMessage.
- body: string
-
nonce: string
Chosen by the client, and echoed on the broadcast or the error, so that it can match the outcome to its pending message. Ignored if longer than 64 characters.
-
replyToId: string
Ignored if longer than 64 characters or naming no message.
- type: "chat_send"
Sent by the chatbox while the user types, every 3 s, and once they pause. The server answers every signed-in socket with ChatTypingUpdateMessage when the user starts or stops, and forgets a typer it hasn't heard from in 6 s.
Sent by the server to every signed-in socket when a user starts or stops typing in the chat, with everyone typing. The chatbox shows their avatars.
Sent by the server when a comment is posted, to every socket if its dump is
public, else to the dump's poster's. WSProvider passes it on to the dump's
page and the dump lists as a comment event, as it does the two messages
below.
Sent by the server when a comment is deleted, as when one is posted.
- commentId: string
-
dumpId: string
Lets a dump's page ignore the comments of other dumps.
- type: "comment_deleted"
Sent by the server to the socket that liked or unliked a comment, as VoteAckMessage is for a vote.
Sent by WSProvider when the user likes a comment, and handled as
VoteCastMessage is, with CommentLikeAckMessage for the ack.
Sent by WSProvider to withdraw a like, as CommentLikeCastMessage.
Sent by the server after a like, as VotesUpdateMessage is after a vote: to the dump's poster alone when the comment is on a private dump.
Sent by the server when a comment is edited, as when one is posted.
Sent by the server when a dump is posted, to every socket if it is public
and to its poster's alone if it is private. It also goes to everyone but the
poster when a private dump goes public, since to them it is new.
WSProvider puts it at the top of its recent dumps.
Sent by the server when a dump is deleted, to every socket if it was public
and to its poster's alone if it was private. It also goes to everyone but
the poster when a public dump goes private. WSProvider drops it from every
list.
Sent by the server when the dumps related to some dumps changed: a note or
a comment gained or lost a link to a dump, or a dump that has such links
turned public. It goes to the sockets whose user may see both ends of a
link. The Dump page showing one of dumpIds fetches its related dumps
again.
-
dumpIds: string[]
The dump whose links changed, then the dumps at their other end, without those this socket's user may not see.
- type: "dump_related_changed"
Sent by the server when a dump changes, to every socket if it is public and
to its poster's alone if it is private, as when it has just gone private.
WSProvider refreshes it in place, without moving it up the feeds.
Sent by the server to the socket whose message failed. With dumpId or
commentId, WSProvider undoes that optimistic vote or like at once rather
than after its 5 s timeout. With scope, the chatbox shows it, on the
pending message nonce names or as a notice. Any other error is ignored.
- action: "cast" | "remove"
- commentId: string
- dumpId: string
-
message: string
In English: the chatbox shows it untranslated.
-
nonce: string
Set only on the failure of a ChatSendMessage that had one.
- scope: "chat"
- type: "error"
Sent by the server to every socket of a user who followed or unfollowed a
user or a playlist, so that FollowProvider in their other tabs refetches
the follow status.
Sent by the notification service to every socket of the notified user.
WSProvider bumps the unread count and chimes.
Sent by the notification service to every socket of a user who opened their
notifications, which marks them all read. WSProvider zeroes the bell's
count, in the other tabs and devices too.
Sent by the server in WelcomeMessage, PresenceUpdateMessage and ChatTypingUpdateMessage, once per signed-in user whatever their number of sockets.
-
avatarVersion: number
Set when the avatar changed while the user was connected, for the client to append to the avatar's URL so it doesn't show the cached one.
- hasAvatar: boolean
- userId: string
- username: string
Sent by the server to every socket every 30 s. WSProvider answers
PongMessage, and a socket that missed the previous ping is closed.
The server also answers a client's ping, though the client never sends one.
Sent by the server when a playlist is created, to every socket if it is
public, else to its owner's. It also goes to everyone but the owner when a
private playlist goes public, since to them it is new. WSProvider passes
it on to the playlist pages as a playlist event, as it does the three
messages below.
Sent by the server when a playlist is deleted, to those who could see it. It also goes to everyone but the owner when a public playlist goes private.
Sent by the server when dumps are added to, removed from or reordered in a playlist, to those who can see it, and when one of its dumps is deleted or changes visibility, which changes what its viewers see of it.
-
dumpIds: string[]
Only the dumps this socket's user may see, in order: another user's private dump is left out.
-
lastDumpAt: Date
When the latest of them was added, the playlist's
lastDumpAtfor this socket's user. It is missing whendumpIdsis empty. - playlistId: string
- type: "playlist_dumps_updated"
Sent by the server when a playlist changes, to every socket if it is public,
else to its owner's, as when it has just gone private. Its dumpCount and
lastDumpAt are the socket's user's, as in playlist_created.
Sent in answer to a PingMessage. The server records the client's to keep its socket open, and the client ignores the server's.
Sent by the server to every socket when a socket opens or closes, and when a connected user's avatar changes.
Sent by the server to every socket after a profile edit, a rename, a role
change or an avatar upload. WSProvider refreshes the user's avatar
wherever it shows, and passes it on as a user event, which updates their
profile and their name on the lists.
Sent by the server to the socket that sent a VoteCastMessage or
VoteRemoveMessage, once the vote is stored. WSProvider confirms
its optimistic vote with it.
Sent by WSProvider when the user upvotes a dump, after it has shown the
vote. The server answers VoteAckMessage, or an ErrorMessage
naming the dump, on which the client undoes the vote, as it does when
neither comes within 5 s.
Sent by WSProvider to withdraw an upvote, as VoteCastMessage.
Sent by the server after a vote, to every socket, or to the poster's alone
for a private dump. WSProvider updates the count, and when voterId is
the user, it updates their votes too, so their other tabs follow.
Sent by the server to a socket once it opens, just after the
PresenceUpdateMessage that announces it. WSProvider replaces its
state with this one, dropping its pending votes and likes. After a
reconnect, it also bumps connectionEpoch, so that pages refetch what they
missed. The per-user fields are empty or zero on an anonymous socket.
| PongMessage
| VoteCastMessage
| VoteRemoveMessage
| CommentLikeCastMessage
| CommentLikeRemoveMessage
| ChatSendMessage
| ChatTypingMessage
| ChatFocusMessage
| ChatEditMessage
| ChatDeleteMessage
| ChatReadMessage
Sent by WSProvider, and dispatched by the route's handleMessage, which
checks each field's type before using it.
| PongMessage
| WelcomeMessage
| PresenceUpdateMessage
| VotesUpdateMessage
| VoteAckMessage
| CommentLikesUpdateMessage
| CommentLikeAckMessage
| DumpCreatedMessage
| DumpUpdatedMessage
| DumpDeletedMessage
| DumpRelatedChangedMessage
| PlaylistCreatedMessage
| PlaylistUpdatedMessage
| PlaylistDeletedMessage
| PlaylistDumpsUpdatedMessage
| UserUpdatedMessage
| CommentCreatedMessage
| CommentUpdatedMessage
| CommentDeletedMessage
| NotificationCreatedMessage
| NotificationsReadMessage
| CategoriesChangedMessage
| ErrorMessage
| ChatMessageMessage
| ChatMessageUpdatedMessage
| ChatMessageDeletedMessage
| ChatTypingUpdateMessage
| ChatReadUpdateMessage
| FollowsChangedMessage
Sent by services/ws-service.ts and the WebSocket route, and handled by
WSProvider's onmessage.
Usage
import * as mod from "shared/ws.ts";