This commit is contained in:
tamaina 2021-09-07 02:40:38 +09:00
parent 4793d1cc56
commit be47a120d7
3 changed files with 19 additions and 15 deletions

View file

@ -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<User['id'], Date> = {};
private emitTypersIntervalId: ReturnType<typeof setInterval>;
@ -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;

View file

@ -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);

View file

@ -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<InternalStreamTypes>;
@ -286,15 +286,17 @@ interface StreamMessages {
name: `adminStream:${User['id']}`;
spec: EventUnionFromDictionary<AdminStreamTypes>;
};
// and notesStream (specにPackedNoteを突っ込むとなぜかバグる)
}
notes: {
name: 'notesStream';
spec: PackedNote;
};
};
//#endregion
// API event definitions
type EventsGenerater<K extends keyof StreamMessages> = { [key in StreamMessages[K]['name']]: (e: StreamMessages[K]['spec']) => void };
type NotesStreamEvent = { notesStream: (e: PackedNote) => void };
export type StreamEventEmitter = Emitter<EventEmitter, EventsGenerater<keyof StreamMessages> & NotesStreamEvent>;
type EventsDictionary = { [x in keyof StreamMessages]: { [y in StreamMessages[x]['name']]: (e: StreamMessages[x]['spec']) => void } };
type Events<D> = (D extends any ? (k: D) => void : never) extends ((k: infer E) => void) ? E : never;
export type StreamEventEmitter = Emitter<EventEmitter, Events<EventsDictionary[keyof StreamMessages]>>;
// provide stream channels union
type ChannelsUnionGenerater<K extends keyof StreamMessages> = StreamMessages[K]['name'];
export type StreamChannels = ChannelsUnionGenerater<keyof StreamMessages> | 'notesStream';
export type StreamChannels = StreamMessages[keyof StreamMessages]['name'] | 'notesStream';