From be47a120d75996864b6bc8a2f393a3ed87aebbb2 Mon Sep 17 00:00:00 2001 From: tamaina Date: Tue, 7 Sep 2021 02:40:38 +0900 Subject: [PATCH] :v: --- src/server/api/stream/channels/messaging.ts | 6 ++++-- src/server/api/stream/index.ts | 8 ++++---- src/server/api/stream/types.ts | 20 +++++++++++--------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/server/api/stream/channels/messaging.ts b/src/server/api/stream/channels/messaging.ts index 015b0a7650..a75181d6d7 100644 --- a/src/server/api/stream/channels/messaging.ts +++ b/src/server/api/stream/channels/messaging.ts @@ -3,6 +3,8 @@ import { readUserMessagingMessage, readGroupMessagingMessage, deliverReadActivit import Channel from '../channel'; import { UserGroupJoinings, Users, MessagingMessages } from '@/models/index'; import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; +import { UserGroup } from '@/models/entities/user-group'; +import { StreamMessages } from '../types'; export default class extends Channel { public readonly chName = 'messaging'; @@ -12,7 +14,7 @@ export default class extends Channel { private otherpartyId: string | null; private otherparty: User | null; private groupId: string | null; - private subCh: string; + private subCh: `messagingStream:${User['id']}-${User['id']}` | `messagingStream:${UserGroup['id']}`; private typers: Record = {}; private emitTypersIntervalId: ReturnType; @@ -45,7 +47,7 @@ export default class extends Channel { } @autobind - private onEvent(data: any) { + private onEvent(data: StreamMessages['messaging']['spec'] | StreamMessages['groupMessaging']['spec']) { if (data.type === 'typing') { const id = data.body; const begin = this.typers[id] == null; diff --git a/src/server/api/stream/index.ts b/src/server/api/stream/index.ts index b2cecb4470..89d9889220 100644 --- a/src/server/api/stream/index.ts +++ b/src/server/api/stream/index.ts @@ -15,7 +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, UserStreams } from './types'; +import { StreamEventEmitter, StreamMessages } from './types'; /** * Main stream connection @@ -47,8 +47,8 @@ export default class Connection { this.wsConnection.on('message', this.onWsConnectionMessage); - this.subscriber.on('broadcast', async ({ type, body }) => { - this.onBroadcastMessage(type, body); + this.subscriber.on('broadcast', async ev => { + this.onBroadcastMessage(ev.type, ev.body); }); if (this.user) { @@ -65,7 +65,7 @@ export default class Connection { } @autobind - private onUserEvent(ev: UserStreams) { // { type, body }と展開すると型も展開されてしまう + private onUserEvent(ev: StreamMessages['user']['spec']) { // { type, body }と展開すると型も展開されてしまう switch (ev.type) { case 'follow': this.following.add(ev.body.id); diff --git a/src/server/api/stream/types.ts b/src/server/api/stream/types.ts index b78b894977..eb80c2e913 100644 --- a/src/server/api/stream/types.ts +++ b/src/server/api/stream/types.ts @@ -29,7 +29,7 @@ import { Page } from '@/models/entities/page'; // 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 = { [K in keyof T]: { type: K; body: T[K]; } } > = U[keyof U]; //#region Stream type-body definitions @@ -225,7 +225,7 @@ export interface AdminStreamTypes { //#endregion //#region 名前とメッセージのペアを中間生成 -interface StreamMessages { +export type StreamMessages = { internal: { name: 'internal'; spec: EventUnionFromDictionary; @@ -286,15 +286,17 @@ interface StreamMessages { name: `adminStream:${User['id']}`; spec: EventUnionFromDictionary; }; - // and notesStream (specにPackedNoteを突っ込むとなぜかバグる) -} + notes: { + name: 'notesStream'; + spec: PackedNote; + }; +}; //#endregion // API event definitions -type EventsGenerater = { [key in StreamMessages[K]['name']]: (e: StreamMessages[K]['spec']) => void }; -type NotesStreamEvent = { notesStream: (e: PackedNote) => void }; -export type StreamEventEmitter = Emitter & NotesStreamEvent>; +type EventsDictionary = { [x in keyof StreamMessages]: { [y in StreamMessages[x]['name']]: (e: StreamMessages[x]['spec']) => void } }; +type Events = (D extends any ? (k: D) => void : never) extends ((k: infer E) => void) ? E : never; +export type StreamEventEmitter = Emitter>; // provide stream channels union -type ChannelsUnionGenerater = StreamMessages[K]['name']; -export type StreamChannels = ChannelsUnionGenerater | 'notesStream'; +export type StreamChannels = StreamMessages[keyof StreamMessages]['name'] | 'notesStream';