diff --git a/package.json b/package.json index ebb4d90897..0f93ae03e9 100644 --- a/package.json +++ b/package.json @@ -209,6 +209,7 @@ "seedrandom": "3.0.5", "sharp": "0.29.0", "speakeasy": "2.0.0", + "strict-event-emitter-types": "2.0.0", "stringz": "2.1.0", "style-loader": "3.2.1", "summaly": "2.4.1", diff --git a/src/server/api/stream/index.ts b/src/server/api/stream/index.ts index 469f28f11c..13011b193e 100644 --- a/src/server/api/stream/index.ts +++ b/src/server/api/stream/index.ts @@ -15,6 +15,7 @@ import { UserProfile } from '@/models/entities/user-profile'; import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream'; import { UserGroup } from '@/models/entities/user-group'; import { PackedNote } from '@/models/repositories/note'; +import { StreamEventEmitter, UserEvent } from './types'; /** * Main stream connection @@ -28,7 +29,7 @@ export default class Connection { public followingChannels: Set = new Set(); public token?: AccessToken; private wsConnection: websocket.connection; - public subscriber: EventEmitter; + public subscriber: StreamEventEmitter; private channels: Channel[] = []; private subscribingNotes: any = {}; private cachedNotes: PackedNote[] = []; @@ -57,14 +58,14 @@ export default class Connection { this.updateFollowingChannels(); this.updateUserProfile(); - this.subscriber.on(`user:${this.user.id}`, ({ type, body }) => { - this.onUserEvent(type, body); + this.subscriber.on(`user:${this.user.id}`, (ev) => { + this.onUserEvent(ev); }); } } @autobind - private onUserEvent(type: string, body: any) { + private onUserEvent({ type, body }: UserEvent) { switch (type) { case 'follow': this.following.add(body.id); diff --git a/src/server/api/stream/types.ts b/src/server/api/stream/types.ts new file mode 100644 index 0000000000..92b3f0fdb5 --- /dev/null +++ b/src/server/api/stream/types.ts @@ -0,0 +1,50 @@ +import { User } from '@/models/entities/user'; +import { EventEmitter } from 'events'; +import Emitter from 'strict-event-emitter-types'; +import StreamTypes from 'misskey-js/built/streaming.types'; +import { Channel } from '@/models/entities/channel'; +import { UserProfile } from '@/models/entities/user-profile'; +import { PackedUser } from '@/models/repositories/user'; + +type Payload void> = T extends (payload: infer P) => void ? P : never; + +// https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type +type EventUnionFromDictionary< + T extends object, + U = { [K in keyof T]: { type: K; body: T[K]} } +> = U[keyof U]; + +export type BroadcastStream = { + name: 'broadcast'; + type: T; + body: Payload; +}; + +export interface UserEventTypes { + terminate: {}; + followChannel: Channel; + unfollowChannel: Channel; + updateUserProfile: UserProfile; + mute: User; + unmute: User; + follow: PackedUser; + unfollow: PackedUser; + userAdded: PackedUser; +}; + +// UserList userRemoved: PackedUser; + +export type UserEventName = `user:${User['id']}`; +export type UserEvent = EventUnionFromDictionary; + +interface StreamEvents { + 'broadcast': (e: BroadcastStream) => void; +} + +interface AuthenticatedStreamEvents { + [key: UserEventName]: (e: UserEvent) => void; + [key: `mainStream:${User['id']}`]: (e: { type: string; body: any }) => void; + [key: `driveStream:${User['id']}`]: (e: { type: string; body: any }) => void; +} + +export type StreamEventEmitter = Emitter; diff --git a/yarn.lock b/yarn.lock index 8151dfe089..33f9f22454 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10249,6 +10249,11 @@ streamsearch@0.1.2: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= +strict-event-emitter-types@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" + integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"