Stores notifications, pushes each new one to its user's sockets as notification_created, and reads them back for routes/notifications.ts. The services of follows, votes, likes, comments, dumps, playlists and the chat call its notify… triggers. Every trigger passes a source key, so the same event never notifies a user twice. What a notification names by id is joined each time it is sent (withCurrentRefs), so its names and links follow renames.

Functions

f
getNotificationsForUser(
userId: string,
page: number,
limit: number
): Page<Notification>

Returns a page of userId's notifications, newest first, with their refs joined, for GET /api/me/notifications.

f
getUnreadCount(userId: string): number

Returns how many of userId's notifications are unread. The WebSocket route sends it in its welcome message, for the bell's count.

f
markAllRead(userId: string): void

Marks every notification of userId read, when they open the /notifications page, and tells all their sockets, so that the bell clears in their other tabs and devices too.

f
notifyCommentOwnerLike(
likerId: string,
commentId: string
): void

Notifies a comment's author that likerId likes it, unless they are the author, and once however often the like is withdrawn and given again.

f
notifyDumpOwnerNewComment(
commenterId: string,
commentId: string,
dumpId: string
): void

Notifies a dump's poster that commenterId commented on it, unless they are the poster. createComment calls it for replies too, but not on an edit.

f
notifyDumpOwnerUpvote(
voterId: string,
dumpId: string
): void

Notifies a dump's poster that voterId upvoted it, unless they are the poster, and once however often the vote is withdrawn and cast again. castVote calls it.

f
notifyEveryone(
mentionerUserId: string,
messageId: string,
skipUserId?: (userId: string) => boolean
): void

Notifies every user but its author of chat message messageId, which says @everyone. The WebSocket route calls it, after notifyMentions so that a user also named is told by name, when the message is sent flagged mentionsEveryone, or when an edit flags it. Each user is notified once per message, however often it is edited. skipUserId spares the users who have the chat open, as for a mention.

f
notifyMentions(
mentionerUserId: string,
body: string,
contextType: "comment" | "dump" | "playlist" | "chat",
contextId: string,
contextTitle: string,
dumpId?: string,
skipUserId?: (userId: string) => boolean
): void

Notifies every user @mentioned in body, except its author, that they were mentioned in the comment, dump, playlist or chat message contextId. Call it again after each edit: a user already notified for this context isn't notified twice. skipUserId spares a mentioned user; the chat uses it for those who have it open.

f
notifyPlaylistFollowersNewDump(
playlistId: string,
playlistTitle: string,
dumpId: string,
dumpTitle: string
): void

Notifies everyone following a playlist that a dump was added to it. The playlist service calls it only when both are public, since a follower can't open a private one.

f
notifyPlaylistFollowersNowPublic(of: { dumpId: string; } | { playlistId: string; }): void

Notifies the followers of each playlist of the dumps in it that became visible to them: a playlist's followers are told of a dump once both are public. The dump service calls it with dumpId when a dump goes public, for each public playlist holding it; the playlist service with playlistId when a playlist goes public, for each public dump in it, from the bottom of the playlist up. A dump the followers were told of before either went private isn't notified again. Adding a dump to a public playlist calls notifyPlaylistFollowersNewDump directly.

f
notifyPlaylistOwnerNewFollower(
followerId: string,
playlistId: string
): void

Notifies a playlist's owner that followerId follows it, unless they are the owner, and once however often they unfollow and follow again. followPlaylist calls it.

f
notifyUserFollowersNewDump(
dumperId: string,
dumpId: string,
dumpTitle: string
): void

Notifies everyone following dumperId that they posted a dump. The dump service calls it for a public dump only, when it is created or goes public. A follower is told of a dump once, however often it goes private and public again.

f
notifyUserNewFollower(
followerId: string,
followedUserId: string
): void

Notifies followedUserId that followerId follows them, once however often they unfollow and follow again. followUser calls it.

f
withCurrentRefs(data: NotificationData): NotificationData

Returns data with what may have changed since it was stored joined from the database: each user's current name, and the slug and owner of its dump and playlist, which the client builds their paths from. A user since deleted keeps their stored name; a deleted dump or playlist gets no ref, and so no link. Every notification the server sends goes through it, and so do the digests.